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 value
= win
->GetThumbPosition();
36 const int id
= win
->GetId();
38 // first send the specific event for the user action
39 wxScrollEvent
evtSpec(eventType
, id
, value
, orient
);
40 evtSpec
.SetEventObject(win
);
41 win
->HandleWindowEvent(evtSpec
);
43 if (!win
->m_isScrolling
)
45 // and if it's over also send a general "changed" event
46 wxScrollEvent
evtChanged(wxEVT_SCROLL_CHANGED
, id
, value
, orient
);
47 evtChanged
.SetEventObject(win
);
48 win
->HandleWindowEvent(evtChanged
);
54 //-----------------------------------------------------------------------------
55 // "button_press_event" from scrollbar
56 //-----------------------------------------------------------------------------
60 gtk_button_press_event(GtkRange
*, GdkEventButton
*, wxScrollBar
* win
)
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
;
81 const int id
= win
->GetId();
83 wxScrollEvent
evtRel(wxEVT_SCROLL_THUMBRELEASE
, id
, value
, orient
);
84 evtRel
.SetEventObject(win
);
85 win
->HandleWindowEvent(evtRel
);
87 wxScrollEvent
evtChanged(wxEVT_SCROLL_CHANGED
, id
, value
, orient
);
88 evtChanged
.SetEventObject(win
);
89 win
->HandleWindowEvent(evtChanged
);
94 //-----------------------------------------------------------------------------
95 // "button_release_event" from scrollbar
96 //-----------------------------------------------------------------------------
100 gtk_button_release_event(GtkRange
* range
, GdkEventButton
*, wxScrollBar
* win
)
102 win
->m_mouseButtonDown
= false;
104 if (win
->m_isScrolling
)
106 win
->m_isScrolling
= false;
107 // Hook up handler to send thumb release event after this emission is finished.
108 // To allow setting scroll position from event handler, sending event must
109 // be deferred until after the GtkRange handler for this signal has run
110 g_signal_handlers_unblock_by_func(range
, (void*)gtk_event_after
, win
);
117 //-----------------------------------------------------------------------------
119 //-----------------------------------------------------------------------------
121 IMPLEMENT_DYNAMIC_CLASS(wxScrollBar
,wxControl
)
123 wxScrollBar::wxScrollBar()
127 wxScrollBar::~wxScrollBar()
131 bool wxScrollBar::Create(wxWindow
*parent
, wxWindowID id
,
132 const wxPoint
& pos
, const wxSize
& size
,
133 long style
, const wxValidator
& validator
, const wxString
& name
)
135 if (!PreCreation( parent
, pos
, size
) ||
136 !CreateBase( parent
, id
, pos
, size
, style
, validator
, name
))
138 wxFAIL_MSG( wxT("wxScrollBar creation failed") );
142 const bool isVertical
= (style
& wxSB_VERTICAL
) != 0;
144 m_widget
= gtk_vscrollbar_new( NULL
);
146 m_widget
= gtk_hscrollbar_new( NULL
);
147 g_object_ref(m_widget
);
149 m_scrollBar
[0] = (GtkRange
*)m_widget
;
151 g_signal_connect_after(m_widget
, "value_changed",
152 G_CALLBACK(gtk_value_changed
), this);
153 g_signal_connect(m_widget
, "button_press_event",
154 G_CALLBACK(gtk_button_press_event
), this);
155 g_signal_connect(m_widget
, "button_release_event",
156 G_CALLBACK(gtk_button_release_event
), this);
159 handler_id
= g_signal_connect(
160 m_widget
, "event_after", G_CALLBACK(gtk_event_after
), this);
161 g_signal_handler_block(m_widget
, handler_id
);
163 m_parent
->DoAddChild( this );
170 int wxScrollBar::GetThumbPosition() const
172 GtkAdjustment
* adj
= ((GtkRange
*)m_widget
)->adjustment
;
173 return int(adj
->value
+ 0.5);
176 int wxScrollBar::GetThumbSize() const
178 GtkAdjustment
* adj
= ((GtkRange
*)m_widget
)->adjustment
;
179 return int(adj
->page_size
);
182 int wxScrollBar::GetPageSize() const
184 GtkAdjustment
* adj
= ((GtkRange
*)m_widget
)->adjustment
;
185 return int(adj
->page_increment
);
188 int wxScrollBar::GetRange() const
190 GtkAdjustment
* adj
= ((GtkRange
*)m_widget
)->adjustment
;
191 return int(adj
->upper
);
194 void wxScrollBar::SetThumbPosition( int viewStart
)
196 if (GetThumbPosition() != viewStart
)
198 g_signal_handlers_block_by_func(m_widget
,
199 (gpointer
)gtk_value_changed
, this);
201 gtk_range_set_value((GtkRange
*)m_widget
, viewStart
);
202 m_scrollPos
[0] = gtk_range_get_value((GtkRange
*)m_widget
);
204 g_signal_handlers_unblock_by_func(m_widget
,
205 (gpointer
)gtk_value_changed
, this);
209 void wxScrollBar::SetScrollbar(int position
, int thumbSize
, int range
, int pageSize
, bool)
213 // GtkRange requires upper > lower
217 GtkAdjustment
* adj
= ((GtkRange
*)m_widget
)->adjustment
;
218 adj
->step_increment
= 1;
219 adj
->page_increment
= pageSize
;
220 adj
->page_size
= thumbSize
;
221 adj
->value
= position
;
222 g_signal_handlers_block_by_func(m_widget
, (void*)gtk_value_changed
, this);
223 gtk_range_set_range((GtkRange
*)m_widget
, 0, range
);
224 m_scrollPos
[0] = adj
->value
;
225 g_signal_handlers_unblock_by_func(m_widget
, (void*)gtk_value_changed
, this);
228 void wxScrollBar::SetPageSize( int pageLength
)
230 SetScrollbar(GetThumbPosition(), GetThumbSize(), GetRange(), pageLength
);
233 void wxScrollBar::SetRange(int range
)
235 SetScrollbar(GetThumbPosition(), GetThumbSize(), range
, GetPageSize());
238 GdkWindow
*wxScrollBar::GTKGetWindow(wxArrayGdkWindows
& WXUNUSED(windows
)) const
240 return m_widget
->window
;
245 wxScrollBar::GetClassDefaultAttributes(wxWindowVariant
WXUNUSED(variant
))
247 return GetDefaultAttributesFromGTKWidget(gtk_vscrollbar_new
);
250 #endif // wxUSE_SCROLLBAR