1 /////////////////////////////////////////////////////////////////////////////
2 // Name: src/gtk/scrolbar.cpp
4 // Author: Robert Roebling
5 // Copyright: (c) 1998 Robert Roebling
6 // Licence: wxWindows licence
7 /////////////////////////////////////////////////////////////////////////////
9 // For compilers that support precompilation, includes "wx.h".
10 #include "wx/wxprec.h"
14 #include "wx/scrolbar.h"
20 #include "wx/gtk/private.h"
22 //-----------------------------------------------------------------------------
23 // "value_changed" from scrollbar
24 //-----------------------------------------------------------------------------
28 gtk_value_changed(GtkRange
* range
, wxScrollBar
* win
)
30 wxEventType eventType
= win
->GTKGetScrollEventType(range
);
31 if (eventType
!= wxEVT_NULL
)
33 const int orient
= win
->HasFlag(wxSB_VERTICAL
) ? wxVERTICAL
: wxHORIZONTAL
;
34 const int value
= win
->GetThumbPosition();
35 const int id
= win
->GetId();
37 // first send the specific event for the user action
38 wxScrollEvent
evtSpec(eventType
, id
, value
, orient
);
39 evtSpec
.SetEventObject(win
);
40 win
->HandleWindowEvent(evtSpec
);
42 if (!win
->m_isScrolling
)
44 // and if it's over also send a general "changed" event
45 wxScrollEvent
evtChanged(wxEVT_SCROLL_CHANGED
, id
, value
, orient
);
46 evtChanged
.SetEventObject(win
);
47 win
->HandleWindowEvent(evtChanged
);
53 //-----------------------------------------------------------------------------
54 // "button_press_event" from scrollbar
55 //-----------------------------------------------------------------------------
59 gtk_button_press_event(GtkRange
*, GdkEventButton
*, wxScrollBar
* win
)
61 win
->m_mouseButtonDown
= true;
66 //-----------------------------------------------------------------------------
67 // "event_after" from scrollbar
68 //-----------------------------------------------------------------------------
72 gtk_event_after(GtkRange
* range
, GdkEvent
* event
, wxScrollBar
* win
)
74 if (event
->type
== GDK_BUTTON_RELEASE
)
76 g_signal_handlers_block_by_func(range
, (void*)gtk_event_after
, win
);
78 const int value
= win
->GetThumbPosition();
79 const int orient
= win
->HasFlag(wxSB_VERTICAL
) ? wxVERTICAL
: wxHORIZONTAL
;
80 const int id
= win
->GetId();
82 wxScrollEvent
evtRel(wxEVT_SCROLL_THUMBRELEASE
, id
, value
, orient
);
83 evtRel
.SetEventObject(win
);
84 win
->HandleWindowEvent(evtRel
);
86 wxScrollEvent
evtChanged(wxEVT_SCROLL_CHANGED
, id
, value
, orient
);
87 evtChanged
.SetEventObject(win
);
88 win
->HandleWindowEvent(evtChanged
);
93 //-----------------------------------------------------------------------------
94 // "button_release_event" from scrollbar
95 //-----------------------------------------------------------------------------
99 gtk_button_release_event(GtkRange
* range
, GdkEventButton
*, wxScrollBar
* win
)
101 win
->m_mouseButtonDown
= false;
103 if (win
->m_isScrolling
)
105 win
->m_isScrolling
= false;
106 // Hook up handler to send thumb release event after this emission is finished.
107 // To allow setting scroll position from event handler, sending event must
108 // be deferred until after the GtkRange handler for this signal has run
109 g_signal_handlers_unblock_by_func(range
, (void*)gtk_event_after
, win
);
116 //-----------------------------------------------------------------------------
118 //-----------------------------------------------------------------------------
120 wxScrollBar::wxScrollBar()
124 wxScrollBar::~wxScrollBar()
128 bool wxScrollBar::Create(wxWindow
*parent
, wxWindowID id
,
129 const wxPoint
& pos
, const wxSize
& size
,
130 long style
, const wxValidator
& validator
, const wxString
& name
)
132 if (!PreCreation( parent
, pos
, size
) ||
133 !CreateBase( parent
, id
, pos
, size
, style
, validator
, name
))
135 wxFAIL_MSG( wxT("wxScrollBar creation failed") );
139 const bool isVertical
= (style
& wxSB_VERTICAL
) != 0;
140 m_widget
= gtk_scrollbar_new(GtkOrientation(isVertical
), NULL
);
141 g_object_ref(m_widget
);
143 m_scrollBar
[0] = (GtkRange
*)m_widget
;
145 g_signal_connect_after(m_widget
, "value_changed",
146 G_CALLBACK(gtk_value_changed
), this);
147 g_signal_connect(m_widget
, "button_press_event",
148 G_CALLBACK(gtk_button_press_event
), this);
149 g_signal_connect(m_widget
, "button_release_event",
150 G_CALLBACK(gtk_button_release_event
), this);
153 handler_id
= g_signal_connect(
154 m_widget
, "event_after", G_CALLBACK(gtk_event_after
), this);
155 g_signal_handler_block(m_widget
, handler_id
);
157 m_parent
->DoAddChild( this );
164 int wxScrollBar::GetThumbPosition() const
166 return wxRound(gtk_range_get_value(GTK_RANGE(m_widget
)));
169 int wxScrollBar::GetThumbSize() const
171 GtkAdjustment
* adj
= gtk_range_get_adjustment(GTK_RANGE(m_widget
));
172 return int(gtk_adjustment_get_page_size(adj
));
175 int wxScrollBar::GetPageSize() const
177 GtkAdjustment
* adj
= gtk_range_get_adjustment(GTK_RANGE(m_widget
));
178 return int(gtk_adjustment_get_page_increment(adj
));
181 int wxScrollBar::GetRange() const
183 GtkAdjustment
* adj
= gtk_range_get_adjustment(GTK_RANGE(m_widget
));
184 return int(gtk_adjustment_get_upper(adj
));
187 void wxScrollBar::SetThumbPosition( int viewStart
)
189 if (GetThumbPosition() != viewStart
)
191 g_signal_handlers_block_by_func(m_widget
,
192 (gpointer
)gtk_value_changed
, this);
194 gtk_range_set_value((GtkRange
*)m_widget
, viewStart
);
195 m_scrollPos
[0] = gtk_range_get_value((GtkRange
*)m_widget
);
197 g_signal_handlers_unblock_by_func(m_widget
,
198 (gpointer
)gtk_value_changed
, this);
202 void wxScrollBar::SetScrollbar(int position
, int thumbSize
, int range
, int pageSize
, bool)
206 // GtkRange requires upper > lower
210 g_signal_handlers_block_by_func(m_widget
, (void*)gtk_value_changed
, this);
211 GtkRange
* widget
= GTK_RANGE(m_widget
);
212 gtk_adjustment_set_page_size(gtk_range_get_adjustment(widget
), thumbSize
);
213 gtk_range_set_increments(widget
, 1, pageSize
);
214 gtk_range_set_range(widget
, 0, range
);
215 gtk_range_set_value(widget
, position
);
216 m_scrollPos
[0] = gtk_range_get_value(widget
);
217 g_signal_handlers_unblock_by_func(m_widget
, (void*)gtk_value_changed
, this);
220 void wxScrollBar::SetPageSize( int pageLength
)
222 SetScrollbar(GetThumbPosition(), GetThumbSize(), GetRange(), pageLength
);
225 void wxScrollBar::SetRange(int range
)
227 SetScrollbar(GetThumbPosition(), GetThumbSize(), range
, GetPageSize());
232 wxScrollBar::GetClassDefaultAttributes(wxWindowVariant
WXUNUSED(variant
))
234 return GetDefaultAttributesFromGTKWidget(gtk_scrollbar_new(GTK_ORIENTATION_VERTICAL
, NULL
));
237 #endif // wxUSE_SCROLLBAR