1 ///////////////////////////////////////////////////////////////////////////// 
   2 // Name:        src/gtk/scrolbar.cpp 
   4 // Author:      Robert Roebling 
   6 // Copyright:   (c) 1998 Robert Roebling 
   7 // Licence:     wxWindows licence 
   8 ///////////////////////////////////////////////////////////////////////////// 
  10 // For compilers that support precompilation, includes "wx.h". 
  11 #include "wx/wxprec.h" 
  15 #include "wx/scrolbar.h" 
  21 #include "wx/gtk/private.h" 
  23 //----------------------------------------------------------------------------- 
  24 // "value_changed" from scrollbar 
  25 //----------------------------------------------------------------------------- 
  29 gtk_value_changed(GtkRange
* range
, wxScrollBar
* win
) 
  31     wxEventType eventType 
= win
->GetScrollEventType(range
); 
  32     if (eventType 
!= wxEVT_NULL
) 
  34         const int orient 
= win
->HasFlag(wxSB_VERTICAL
) ? wxVERTICAL 
: wxHORIZONTAL
; 
  35         const int i 
= orient 
== wxVERTICAL
; 
  36         const int value 
= win
->GetThumbPosition(); 
  37         wxScrollEvent 
event(eventType
, win
->GetId(), value
, orient
); 
  38         event
.SetEventObject(win
); 
  39         win
->m_blockValueChanged
[i
] = true; 
  40         win
->GetEventHandler()->ProcessEvent(event
); 
  41         if (!win
->m_isScrolling
) 
  43             wxScrollEvent 
event(wxEVT_SCROLL_CHANGED
, win
->GetId(), value
, orient
); 
  44             event
.SetEventObject(win
); 
  45             win
->GetEventHandler()->ProcessEvent(event
); 
  47         win
->m_blockValueChanged
[i
] = false; 
  52 //----------------------------------------------------------------------------- 
  53 // "button_press_event" from scrollbar 
  54 //----------------------------------------------------------------------------- 
  58 gtk_button_press_event(GtkRange
*, GdkEventButton
*, wxScrollBar
* win
) 
  60     if (g_isIdle
) wxapp_install_idle_handler(); 
  62     win
->m_mouseButtonDown 
= true; 
  67 //----------------------------------------------------------------------------- 
  68 // "event_after" from scrollbar 
  69 //----------------------------------------------------------------------------- 
  73 gtk_event_after(GtkRange
* range
, GdkEvent
* event
, wxScrollBar
* win
) 
  75     if (event
->type 
== GDK_BUTTON_RELEASE
) 
  77         g_signal_handlers_block_by_func(range
, (void*)gtk_event_after
, win
); 
  79         const int value 
= win
->GetThumbPosition(); 
  80         const int orient 
= win
->HasFlag(wxSB_VERTICAL
) ? wxVERTICAL 
: wxHORIZONTAL
; 
  82         wxScrollEvent 
event(wxEVT_SCROLL_THUMBRELEASE
, win
->GetId(), value
, orient
); 
  83         event
.SetEventObject(win
); 
  84         win
->GetEventHandler()->ProcessEvent(event
); 
  86         wxScrollEvent 
event2(wxEVT_SCROLL_CHANGED
, win
->GetId(), value
, orient
); 
  87         event2
.SetEventObject(win
); 
  88         win
->GetEventHandler()->ProcessEvent(event2
); 
  93 //----------------------------------------------------------------------------- 
  94 // "button_release_event" from scrollbar 
  95 //----------------------------------------------------------------------------- 
  99 gtk_button_release_event(GtkRange
* range
, GdkEventButton
*, wxScrollBar
* win
) 
 102         wxapp_install_idle_handler(); 
 104     win
->m_mouseButtonDown 
= false; 
 106     if (win
->m_isScrolling
) 
 108         win
->m_isScrolling 
= false; 
 109         // Hook up handler to send thumb release event after this emission is finished. 
 110         // To allow setting scroll position from event handler, sending event must 
 111         // be deferred until after the GtkRange handler for this signal has run 
 112         g_signal_handlers_unblock_by_func(range
, (void*)gtk_event_after
, win
); 
 119 //----------------------------------------------------------------------------- 
 121 //----------------------------------------------------------------------------- 
 123 IMPLEMENT_DYNAMIC_CLASS(wxScrollBar
,wxControl
) 
 125 wxScrollBar::wxScrollBar() 
 129 wxScrollBar::~wxScrollBar() 
 133 bool wxScrollBar::Create(wxWindow 
*parent
, wxWindowID id
, 
 134            const wxPoint
& pos
, const wxSize
& size
, 
 135            long style
, const wxValidator
& validator
, const wxString
& name 
) 
 138     m_acceptsFocus 
= true; 
 140     if (!PreCreation( parent
, pos
, size 
) || 
 141         !CreateBase( parent
, id
, pos
, size
, style
, validator
, name 
)) 
 143         wxFAIL_MSG( wxT("wxScrollBar creation failed") ); 
 147     const bool isVertical 
= (style 
& wxSB_VERTICAL
) != 0; 
 149         m_widget 
= gtk_vscrollbar_new( (GtkAdjustment 
*) NULL 
); 
 151         m_widget 
= gtk_hscrollbar_new( (GtkAdjustment 
*) NULL 
); 
 153     m_scrollBar
[int(isVertical
)] = (GtkRange
*)m_widget
; 
 155     g_signal_connect(m_widget
, "value_changed", 
 156                      G_CALLBACK(gtk_value_changed
), this); 
 157     g_signal_connect(m_widget
, "button_press_event", 
 158                      G_CALLBACK(gtk_button_press_event
), this); 
 159     g_signal_connect(m_widget
, "button_release_event", 
 160                      G_CALLBACK(gtk_button_release_event
), this); 
 163     handler_id 
= g_signal_connect( 
 164         m_widget
, "event_after", G_CALLBACK(gtk_event_after
), this); 
 165     g_signal_handler_block(m_widget
, handler_id
); 
 167     m_parent
->DoAddChild( this ); 
 174 int wxScrollBar::GetThumbPosition() const 
 176     GtkAdjustment
* adj 
= ((GtkRange
*)m_widget
)->adjustment
; 
 177     return int(adj
->value 
+ 0.5); 
 180 int wxScrollBar::GetThumbSize() const 
 182     GtkAdjustment
* adj 
= ((GtkRange
*)m_widget
)->adjustment
; 
 183     return int(adj
->page_size
); 
 186 int wxScrollBar::GetPageSize() const 
 188     GtkAdjustment
* adj 
= ((GtkRange
*)m_widget
)->adjustment
; 
 189     return int(adj
->page_increment
); 
 192 int wxScrollBar::GetRange() const 
 194     GtkAdjustment
* adj 
= ((GtkRange
*)m_widget
)->adjustment
; 
 195     return int(adj
->upper
); 
 198 void wxScrollBar::SetThumbPosition( int viewStart 
) 
 200     if (GetThumbPosition() != viewStart
) 
 202         GtkAdjustment
* adj 
= ((GtkRange
*)m_widget
)->adjustment
; 
 203         const int i 
= (GtkRange
*)m_widget 
== m_scrollBar
[1]; 
 204         const int max 
= int(adj
->upper 
- adj
->page_size
); 
 211         adj
->value 
= viewStart
; 
 212         // If a "value_changed" signal emission is not already in progress 
 213         if (!m_blockValueChanged
[i
]) 
 215             gtk_adjustment_value_changed(adj
); 
 220 void wxScrollBar::SetScrollbar(int position
, int thumbSize
, int range
, int pageSize
, bool) 
 224         // GtkRange requires upper > lower 
 228     if (position 
> range 
- thumbSize
) 
 229         position 
= range 
- thumbSize
; 
 232     GtkAdjustment
* adj 
= ((GtkRange
*)m_widget
)->adjustment
; 
 233     adj
->step_increment 
= 1; 
 234     adj
->page_increment 
= pageSize
; 
 235     adj
->page_size 
= thumbSize
; 
 237     SetThumbPosition(position
); 
 238     gtk_adjustment_changed(adj
); 
 241 void wxScrollBar::SetPageSize( int pageLength 
) 
 243     SetScrollbar(GetThumbPosition(), GetThumbSize(), GetRange(), pageLength
); 
 246 void wxScrollBar::SetRange(int range
) 
 248     SetScrollbar(GetThumbPosition(), GetThumbSize(), range
, GetPageSize()); 
 251 bool wxScrollBar::IsOwnGtkWindow( GdkWindow 
*window 
) 
 253     GtkRange 
*range 
= GTK_RANGE(m_widget
); 
 254     return ( (window 
== GTK_WIDGET(range
)->window
) ); 
 259 wxScrollBar::GetClassDefaultAttributes(wxWindowVariant 
WXUNUSED(variant
)) 
 261     return GetDefaultAttributesFromGTKWidget(gtk_vscrollbar_new
); 
 264 #endif // wxUSE_SCROLLBAR