1 ///////////////////////////////////////////////////////////////////////////// 
   4 // Author:      Robert Roebling 
   6 // Copyright:   (c) 1998 Robert Roebling 
   7 // Licence:           wxWindows licence 
   8 ///////////////////////////////////////////////////////////////////////////// 
  12 #pragma implementation "scrolbar.h" 
  15 #include "wx/scrolbar.h" 
  26 //----------------------------------------------------------------------------- 
  28 //----------------------------------------------------------------------------- 
  30 extern void wxapp_install_idle_handler(); 
  33 //----------------------------------------------------------------------------- 
  35 //----------------------------------------------------------------------------- 
  37 extern bool   g_blockEventsOnDrag
; 
  38 extern bool   g_blockEventsOnScroll
; 
  40 static const float sensitivity 
= 0.02; 
  42 //----------------------------------------------------------------------------- 
  44 //----------------------------------------------------------------------------- 
  46 static void gtk_scrollbar_callback( GtkAdjustment 
*adjust
, wxScrollBar 
*win 
) 
  48     if (g_isIdle
) wxapp_install_idle_handler(); 
  50     if (!win
->m_hasVMT
) return; 
  51     if (g_blockEventsOnDrag
) return; 
  53     float diff 
= adjust
->value 
- win
->m_oldPos
; 
  54     if (fabs(diff
) < sensitivity
) return; 
  56     win
->m_oldPos 
= adjust
->value
; 
  58     GtkRange 
*range 
= GTK_RANGE( win
->m_widget 
); 
  60     wxEventType command 
= wxEVT_SCROLL_THUMBTRACK
; 
  61     if      (range
->scroll_type 
== GTK_SCROLL_STEP_BACKWARD
) command 
= wxEVT_SCROLL_LINEUP
; 
  62     else if (range
->scroll_type 
== GTK_SCROLL_STEP_FORWARD
)  command 
= wxEVT_SCROLL_LINEDOWN
; 
  63     else if (range
->scroll_type 
== GTK_SCROLL_PAGE_BACKWARD
) command 
= wxEVT_SCROLL_PAGEUP
; 
  64     else if (range
->scroll_type 
== GTK_SCROLL_PAGE_FORWARD
)  command 
= wxEVT_SCROLL_PAGEDOWN
; 
  66     double dvalue 
= adjust
->value
; 
  67     int value 
= (int)(dvalue 
>= 0 ? dvalue 
- 0.5 : dvalue 
+ 0.5); 
  69     int orient 
= win
->HasFlag(wxSB_VERTICAL
) ? wxVERTICAL 
: wxHORIZONTAL
; 
  71     wxScrollEvent 
event( command
, win
->GetId(), value
, orient 
); 
  72     event
.SetEventObject( win 
); 
  73     win
->GetEventHandler()->ProcessEvent( event 
); 
  76     wxCommandEvent cevent( wxEVT_COMMAND_SCROLLBAR_UPDATED, win->GetId() ); 
  77     cevent.SetEventObject( win ); 
  78     win->ProcessEvent( cevent ); 
  82 //----------------------------------------------------------------------------- 
  83 // "button_press_event" from slider 
  84 //----------------------------------------------------------------------------- 
  86 static gint 
gtk_scrollbar_button_press_callback( GtkRange 
*widget
,  
  87                                                  GdkEventButton 
*gdk_event
,  
  90     if (g_isIdle
) wxapp_install_idle_handler(); 
  92 //  g_blockEventsOnScroll = TRUE;  doesn't work in DialogEd 
  94     win
->m_isScrolling 
= (gdk_event
->window 
== widget
->slider
); 
  99 //----------------------------------------------------------------------------- 
 100 // "button_release_event" from slider 
 101 //----------------------------------------------------------------------------- 
 103 static gint 
gtk_scrollbar_button_release_callback( GtkRange 
*WXUNUSED(widget
),  
 104                                                    GdkEventButton 
*WXUNUSED(gdk_event
),  
 107     if (g_isIdle
) wxapp_install_idle_handler(); 
 109 //  g_blockEventsOnScroll = FALSE; 
 111     if (win
->m_isScrolling
) 
 113         wxEventType command 
= wxEVT_SCROLL_THUMBRELEASE
; 
 114         int value 
= (int)ceil(win
->m_adjust
->value
); 
 115         int dir 
= win
->HasFlag(wxSB_VERTICAL
) ? wxVERTICAL 
: wxHORIZONTAL
; 
 117         wxScrollEvent 
event( command
, value
, dir 
); 
 118         event
.SetEventObject( win 
); 
 119         win
->GetEventHandler()->ProcessEvent( event 
); 
 122     win
->m_isScrolling 
= FALSE
; 
 127 //----------------------------------------------------------------------------- 
 129 //----------------------------------------------------------------------------- 
 131 IMPLEMENT_DYNAMIC_CLASS(wxScrollBar
,wxControl
) 
 133 wxScrollBar::~wxScrollBar() 
 137 bool wxScrollBar::Create(wxWindow 
*parent
, wxWindowID id
, 
 138            const wxPoint
& pos
, const wxSize
& size
, 
 139            long style
, const wxValidator
& validator
, const wxString
& name 
) 
 142     m_acceptsFocus 
= TRUE
; 
 144     if (!PreCreation( parent
, pos
, size 
) || 
 145         !CreateBase( parent
, id
, pos
, size
, style
, validator
, name 
)) 
 147         wxFAIL_MSG( wxT("wxScrollBar creation failed") ); 
 153     if ((style 
& wxSB_VERTICAL
) == wxSB_VERTICAL
) 
 154         m_widget 
= gtk_vscrollbar_new( (GtkAdjustment 
*) NULL 
); 
 156         m_widget 
= gtk_hscrollbar_new( (GtkAdjustment 
*) NULL 
); 
 158     m_adjust 
= gtk_range_get_adjustment( GTK_RANGE(m_widget
) ); 
 160     gtk_signal_connect( GTK_OBJECT(m_adjust
),  
 162                         (GtkSignalFunc
) gtk_scrollbar_callback
,  
 165     gtk_signal_connect( GTK_OBJECT(m_widget
),  
 166                         "button_press_event", 
 167                         (GtkSignalFunc
)gtk_scrollbar_button_press_callback
,  
 170     gtk_signal_connect( GTK_OBJECT(m_widget
),  
 171                         "button_release_event", 
 172                         (GtkSignalFunc
)gtk_scrollbar_button_release_callback
,  
 175     m_parent
->DoAddChild( this ); 
 179     SetBackgroundColour( parent
->GetBackgroundColour() ); 
 186 int wxScrollBar::GetThumbPosition() const 
 188     double val 
= m_adjust
->value
; 
 189     return (int)(val 
>= 0 ? val 
- 0.5 : val 
+ 0.5); 
 192 int wxScrollBar::GetThumbSize() const 
 194     return (int)(m_adjust
->page_size
+0.5); 
 197 int wxScrollBar::GetPageSize() const 
 199     return (int)(m_adjust
->page_increment
+0.5); 
 202 int wxScrollBar::GetRange() const 
 204     return (int)(m_adjust
->upper
+0.5); 
 207 void wxScrollBar::SetThumbPosition( int viewStart 
) 
 209     if (m_isScrolling
) return; 
 211     float fpos 
= (float)viewStart
; 
 213     if (fabs(fpos
-m_adjust
->value
) < 0.2) return; 
 214     m_adjust
->value 
= fpos
; 
 216     gtk_signal_disconnect_by_func( GTK_OBJECT(m_adjust
),  
 217                         (GtkSignalFunc
) gtk_scrollbar_callback
,  
 220     gtk_signal_emit_by_name( GTK_OBJECT(m_adjust
), "value_changed" ); 
 222     gtk_signal_connect( GTK_OBJECT(m_adjust
),  
 224                         (GtkSignalFunc
) gtk_scrollbar_callback
,  
 228 void wxScrollBar::SetScrollbar( int position
, int thumbSize
, int range
, int pageSize
, 
 229       bool WXUNUSED(refresh
) ) 
 231     float fpos 
= (float)position
; 
 232     float frange 
= (float)range
; 
 233     float fthumb 
= (float)thumbSize
; 
 234     float fpage 
= (float)pageSize
; 
 236     if ((fabs(frange
-m_adjust
->upper
) < 0.2) && 
 237         (fabs(fthumb
-m_adjust
->page_size
) < 0.2) && 
 238         (fabs(fpage
-m_adjust
->page_increment
) < 0.2)) 
 240         SetThumbPosition( position 
); 
 246     m_adjust
->lower 
= 0.0; 
 247     m_adjust
->upper 
= frange
; 
 248     m_adjust
->value 
= fpos
; 
 249     m_adjust
->step_increment 
= 1.0; 
 250     m_adjust
->page_increment 
= (float)(wxMax(fpage
,0)); 
 251     m_adjust
->page_size 
= fthumb
; 
 253     gtk_signal_emit_by_name( GTK_OBJECT(m_adjust
), "changed" ); 
 256 /* Backward compatibility */ 
 257 int wxScrollBar::GetValue() const 
 259     return GetThumbPosition(); 
 262 void wxScrollBar::SetValue( int viewStart 
) 
 264     SetThumbPosition( viewStart 
); 
 267 void wxScrollBar::GetValues( int *viewStart
, int *viewLength
, int *objectLength
, int *pageLength 
) const 
 269     int pos 
= (int)(m_adjust
->value
+0.5); 
 270     int thumb 
= (int)(m_adjust
->page_size
+0.5); 
 271     int page 
= (int)(m_adjust
->page_increment
+0.5); 
 272     int range 
= (int)(m_adjust
->upper
+0.5); 
 276     *objectLength 
= thumb
; 
 280 int wxScrollBar::GetViewLength() const 
 282     return (int)(m_adjust
->upper
+0.5); 
 285 int wxScrollBar::GetObjectLength() const 
 287     return (int)(m_adjust
->page_size
+0.5); 
 290 void wxScrollBar::SetPageSize( int pageLength 
) 
 292     int pos 
= (int)(m_adjust
->value
+0.5); 
 293     int thumb 
= (int)(m_adjust
->page_size
+0.5); 
 294     int range 
= (int)(m_adjust
->upper
+0.5); 
 295     SetScrollbar( pos
, thumb
, range
, pageLength 
); 
 298 void wxScrollBar::SetObjectLength( int objectLength 
) 
 300     int pos 
= (int)(m_adjust
->value
+0.5); 
 301     int page 
= (int)(m_adjust
->page_increment
+0.5); 
 302     int range 
= (int)(m_adjust
->upper
+0.5); 
 303     SetScrollbar( pos
, objectLength
, range
, page 
); 
 306 void wxScrollBar::SetViewLength( int viewLength 
) 
 308     int pos 
= (int)(m_adjust
->value
+0.5); 
 309     int thumb 
= (int)(m_adjust
->page_size
+0.5); 
 310     int page 
= (int)(m_adjust
->page_increment
+0.5); 
 311     SetScrollbar( pos
, thumb
, viewLength
, page 
); 
 314 bool wxScrollBar::IsOwnGtkWindow( GdkWindow 
*window 
) 
 316     GtkRange 
*range 
= GTK_RANGE(m_widget
); 
 317     return ( (window 
== GTK_WIDGET(range
)->window
) || 
 318              (window 
== range
->trough
) || 
 319              (window 
== range
->slider
) || 
 320              (window 
== range
->step_forw
) || 
 321              (window 
== range
->step_back
) ); 
 324 void wxScrollBar::ApplyWidgetStyle() 
 327     gtk_widget_set_style( m_widget
, m_widgetStyle 
);