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