]> git.saurik.com Git - wxWidgets.git/blame - src/gtk1/scrolbar.cpp
since DoScreenToClient and ClientToScreen in toplvlcmn are implemented by calling...
[wxWidgets.git] / src / gtk1 / scrolbar.cpp
CommitLineData
c801d85f 1/////////////////////////////////////////////////////////////////////////////
1e6feb95 2// Name: src/gtk/scrolbar.cpp
c801d85f
KB
3// Purpose:
4// Author: Robert Roebling
f96aa4d9
RR
5// Id: $Id$
6// Copyright: (c) 1998 Robert Roebling
1e6feb95 7// Licence: wxWindows licence
c801d85f
KB
8/////////////////////////////////////////////////////////////////////////////
9
10
11#ifdef __GNUG__
12#pragma implementation "scrolbar.h"
13#endif
14
1e6feb95 15#include "wx/defs.h"
dcf924a3
RR
16
17#if wxUSE_SCROLLBAR
18
1e6feb95
VZ
19#include "wx/scrolbar.h"
20
c801d85f 21#include "wx/utils.h"
aed8ac3f 22
f5368809 23#include <math.h>
c801d85f 24
aed8ac3f
RR
25#include <gdk/gdk.h>
26#include <gtk/gtk.h>
83624f79 27
acfd422a
RR
28//-----------------------------------------------------------------------------
29// idle system
30//-----------------------------------------------------------------------------
31
32extern void wxapp_install_idle_handler();
33extern bool g_isIdle;
34
66bd6b93
RR
35//-----------------------------------------------------------------------------
36// data
37//-----------------------------------------------------------------------------
38
39extern bool g_blockEventsOnDrag;
76ed8f8d 40extern bool g_blockEventsOnScroll;
66bd6b93 41
aed8ac3f
RR
42static const float sensitivity = 0.02;
43
c801d85f 44//-----------------------------------------------------------------------------
b4071e91 45// "value_changed"
c801d85f
KB
46//-----------------------------------------------------------------------------
47
e1811a01 48static void gtk_scrollbar_callback( GtkAdjustment *adjust, wxScrollBar *win )
c801d85f 49{
acfd422a
RR
50 if (g_isIdle) wxapp_install_idle_handler();
51
a2053b27 52 if (!win->m_hasVMT) return;
2d17d68f 53 if (g_blockEventsOnDrag) return;
c801d85f 54
e1811a01 55 float diff = adjust->value - win->m_oldPos;
aed8ac3f 56 if (fabs(diff) < sensitivity) return;
e1811a01
RR
57
58 win->m_oldPos = adjust->value;
59
60 GtkRange *range = GTK_RANGE( win->m_widget );
61
62 wxEventType command = wxEVT_SCROLL_THUMBTRACK;
63 if (range->scroll_type == GTK_SCROLL_STEP_BACKWARD) command = wxEVT_SCROLL_LINEUP;
64 else if (range->scroll_type == GTK_SCROLL_STEP_FORWARD) command = wxEVT_SCROLL_LINEDOWN;
65 else if (range->scroll_type == GTK_SCROLL_PAGE_BACKWARD) command = wxEVT_SCROLL_PAGEUP;
66 else if (range->scroll_type == GTK_SCROLL_PAGE_FORWARD) command = wxEVT_SCROLL_PAGEDOWN;
67
0a07a7d8 68 double dvalue = adjust->value;
a9f21e71 69 int value = (int)(dvalue < 0 ? dvalue - 0.5 : dvalue + 0.5);
c801d85f 70
f03fc89f 71 int orient = win->HasFlag(wxSB_VERTICAL) ? wxVERTICAL : wxHORIZONTAL;
c801d85f 72
2d17d68f
RR
73 wxScrollEvent event( command, win->GetId(), value, orient );
74 event.SetEventObject( win );
75 win->GetEventHandler()->ProcessEvent( event );
c801d85f
KB
76
77/*
2d17d68f
RR
78 wxCommandEvent cevent( wxEVT_COMMAND_SCROLLBAR_UPDATED, win->GetId() );
79 cevent.SetEventObject( win );
80 win->ProcessEvent( cevent );
c801d85f 81*/
6de97a3b 82}
c801d85f 83
cb43b372
RR
84//-----------------------------------------------------------------------------
85// "button_press_event" from slider
86//-----------------------------------------------------------------------------
87
2a23d363
RR
88static gint gtk_scrollbar_button_press_callback( GtkRange *widget,
89 GdkEventButton *gdk_event,
f03fc89f 90 wxScrollBar *win )
cb43b372 91{
acfd422a
RR
92 if (g_isIdle) wxapp_install_idle_handler();
93
1ecc4d80 94// g_blockEventsOnScroll = TRUE; doesn't work in DialogEd
2a23d363
RR
95
96 win->m_isScrolling = (gdk_event->window == widget->slider);
cb43b372 97
acfd422a 98 return FALSE;
cb43b372
RR
99}
100
101//-----------------------------------------------------------------------------
102// "button_release_event" from slider
103//-----------------------------------------------------------------------------
104
76ed8f8d
RR
105static gint gtk_scrollbar_button_release_callback( GtkRange *WXUNUSED(widget),
106 GdkEventButton *WXUNUSED(gdk_event),
f03fc89f 107 wxScrollBar *win )
cb43b372 108{
acfd422a 109 if (g_isIdle) wxapp_install_idle_handler();
88413fec 110
1ecc4d80 111// g_blockEventsOnScroll = FALSE;
cb43b372 112
2a23d363
RR
113 if (win->m_isScrolling)
114 {
7d56fb8f 115 wxEventType command = wxEVT_SCROLL_THUMBRELEASE;
2a23d363
RR
116 int value = (int)ceil(win->m_adjust->value);
117 int dir = win->HasFlag(wxSB_VERTICAL) ? wxVERTICAL : wxHORIZONTAL;
118
119 wxScrollEvent event( command, value, dir );
2a23d363
RR
120 event.SetEventObject( win );
121 win->GetEventHandler()->ProcessEvent( event );
122 }
76ed8f8d 123
2a23d363
RR
124 win->m_isScrolling = FALSE;
125
2d17d68f 126 return FALSE;
cb43b372
RR
127}
128
b4071e91
RR
129//-----------------------------------------------------------------------------
130// wxScrollBar
131//-----------------------------------------------------------------------------
132
c801d85f
KB
133IMPLEMENT_DYNAMIC_CLASS(wxScrollBar,wxControl)
134
0a07a7d8 135wxScrollBar::~wxScrollBar()
c801d85f 136{
6de97a3b 137}
c801d85f 138
debe6624 139bool wxScrollBar::Create(wxWindow *parent, wxWindowID id,
c801d85f 140 const wxPoint& pos, const wxSize& size,
6de97a3b 141 long style, const wxValidator& validator, const wxString& name )
c801d85f 142{
2d17d68f
RR
143 m_needParent = TRUE;
144 m_acceptsFocus = TRUE;
c801d85f 145
4dcaf11a
RR
146 if (!PreCreation( parent, pos, size ) ||
147 !CreateBase( parent, id, pos, size, style, validator, name ))
148 {
223d09f6 149 wxFAIL_MSG( wxT("wxScrollBar creation failed") );
0a07a7d8 150 return FALSE;
4dcaf11a 151 }
6de97a3b 152
2d17d68f 153 m_oldPos = 0.0;
c801d85f 154
d9bd1494 155 if ((style & wxSB_VERTICAL) == wxSB_VERTICAL)
2d17d68f 156 m_widget = gtk_vscrollbar_new( (GtkAdjustment *) NULL );
d9bd1494
SB
157 else
158 m_widget = gtk_hscrollbar_new( (GtkAdjustment *) NULL );
159
2d17d68f 160 m_adjust = gtk_range_get_adjustment( GTK_RANGE(m_widget) );
c801d85f 161
2d17d68f
RR
162 gtk_signal_connect( GTK_OBJECT(m_adjust),
163 "value_changed",
f03fc89f
VZ
164 (GtkSignalFunc) gtk_scrollbar_callback,
165 (gpointer) this );
c801d85f 166
2d17d68f
RR
167 gtk_signal_connect( GTK_OBJECT(m_widget),
168 "button_press_event",
169 (GtkSignalFunc)gtk_scrollbar_button_press_callback,
f03fc89f 170 (gpointer) this );
cb43b372 171
2d17d68f
RR
172 gtk_signal_connect( GTK_OBJECT(m_widget),
173 "button_release_event",
174 (GtkSignalFunc)gtk_scrollbar_button_release_callback,
f03fc89f 175 (gpointer) this );
cb43b372 176
f03fc89f 177 m_parent->DoAddChild( this );
6ca41e57 178
2d17d68f 179 PostCreation();
c801d85f 180
2d17d68f 181 SetBackgroundColour( parent->GetBackgroundColour() );
f96aa4d9 182
2d17d68f 183 Show( TRUE );
c801d85f 184
2d17d68f 185 return TRUE;
6de97a3b 186}
c801d85f 187
0a07a7d8 188int wxScrollBar::GetThumbPosition() const
c801d85f 189{
0a07a7d8 190 double val = m_adjust->value;
a9f21e71 191 return (int)(val < 0 ? val - 0.5 : val + 0.5);
6de97a3b 192}
c801d85f
KB
193
194int wxScrollBar::GetThumbSize() const
195{
2d17d68f 196 return (int)(m_adjust->page_size+0.5);
6de97a3b 197}
c801d85f
KB
198
199int wxScrollBar::GetPageSize() const
200{
2d17d68f 201 return (int)(m_adjust->page_increment+0.5);
6de97a3b 202}
c801d85f
KB
203
204int wxScrollBar::GetRange() const
205{
2d17d68f 206 return (int)(m_adjust->upper+0.5);
6de97a3b 207}
c801d85f 208
4fabb575 209void wxScrollBar::SetThumbPosition( int viewStart )
c801d85f 210{
2d17d68f 211 if (m_isScrolling) return;
76ed8f8d 212
2d17d68f
RR
213 float fpos = (float)viewStart;
214 m_oldPos = fpos;
215 if (fabs(fpos-m_adjust->value) < 0.2) return;
216 m_adjust->value = fpos;
76ed8f8d 217
2a23d363
RR
218 gtk_signal_disconnect_by_func( GTK_OBJECT(m_adjust),
219 (GtkSignalFunc) gtk_scrollbar_callback,
220 (gpointer) this );
221
2d17d68f 222 gtk_signal_emit_by_name( GTK_OBJECT(m_adjust), "value_changed" );
2a23d363
RR
223
224 gtk_signal_connect( GTK_OBJECT(m_adjust),
225 "value_changed",
226 (GtkSignalFunc) gtk_scrollbar_callback,
227 (gpointer) this );
6de97a3b 228}
c801d85f 229
debe6624
JS
230void wxScrollBar::SetScrollbar( int position, int thumbSize, int range, int pageSize,
231 bool WXUNUSED(refresh) )
c801d85f 232{
2d17d68f
RR
233 float fpos = (float)position;
234 float frange = (float)range;
235 float fthumb = (float)thumbSize;
236 float fpage = (float)pageSize;
c801d85f 237
2d17d68f
RR
238 if ((fabs(frange-m_adjust->upper) < 0.2) &&
239 (fabs(fthumb-m_adjust->page_size) < 0.2) &&
240 (fabs(fpage-m_adjust->page_increment) < 0.2))
241 {
242 SetThumbPosition( position );
243 return;
244 }
84efdbf1 245
2d17d68f 246 m_oldPos = fpos;
cb43b372 247
2d17d68f
RR
248 m_adjust->lower = 0.0;
249 m_adjust->upper = frange;
250 m_adjust->value = fpos;
251 m_adjust->step_increment = 1.0;
252 m_adjust->page_increment = (float)(wxMax(fpage,0));
253 m_adjust->page_size = fthumb;
254
255 gtk_signal_emit_by_name( GTK_OBJECT(m_adjust), "changed" );
6de97a3b 256}
c801d85f 257
2d17d68f 258/* Backward compatibility */
0a07a7d8 259int wxScrollBar::GetValue() const
c801d85f 260{
2d17d68f 261 return GetThumbPosition();
6de97a3b 262}
c801d85f 263
debe6624 264void wxScrollBar::SetValue( int viewStart )
c801d85f 265{
2d17d68f 266 SetThumbPosition( viewStart );
6de97a3b 267}
c801d85f
KB
268
269void wxScrollBar::GetValues( int *viewStart, int *viewLength, int *objectLength, int *pageLength ) const
270{
2d17d68f
RR
271 int pos = (int)(m_adjust->value+0.5);
272 int thumb = (int)(m_adjust->page_size+0.5);
273 int page = (int)(m_adjust->page_increment+0.5);
274 int range = (int)(m_adjust->upper+0.5);
c801d85f 275
2d17d68f
RR
276 *viewStart = pos;
277 *viewLength = range;
278 *objectLength = thumb;
279 *pageLength = page;
6de97a3b 280}
c801d85f
KB
281
282int wxScrollBar::GetViewLength() const
283{
2d17d68f 284 return (int)(m_adjust->upper+0.5);
6de97a3b 285}
c801d85f
KB
286
287int wxScrollBar::GetObjectLength() const
288{
2d17d68f 289 return (int)(m_adjust->page_size+0.5);
6de97a3b 290}
c801d85f 291
debe6624 292void wxScrollBar::SetPageSize( int pageLength )
c801d85f 293{
2d17d68f
RR
294 int pos = (int)(m_adjust->value+0.5);
295 int thumb = (int)(m_adjust->page_size+0.5);
296 int range = (int)(m_adjust->upper+0.5);
297 SetScrollbar( pos, thumb, range, pageLength );
6de97a3b 298}
c801d85f 299
debe6624 300void wxScrollBar::SetObjectLength( int objectLength )
c801d85f 301{
2d17d68f
RR
302 int pos = (int)(m_adjust->value+0.5);
303 int page = (int)(m_adjust->page_increment+0.5);
304 int range = (int)(m_adjust->upper+0.5);
305 SetScrollbar( pos, objectLength, range, page );
6de97a3b 306}
c801d85f 307
debe6624 308void wxScrollBar::SetViewLength( int viewLength )
c801d85f 309{
2d17d68f
RR
310 int pos = (int)(m_adjust->value+0.5);
311 int thumb = (int)(m_adjust->page_size+0.5);
312 int page = (int)(m_adjust->page_increment+0.5);
313 SetScrollbar( pos, thumb, viewLength, page );
6de97a3b 314}
c801d85f 315
b4071e91
RR
316bool wxScrollBar::IsOwnGtkWindow( GdkWindow *window )
317{
2d17d68f
RR
318 GtkRange *range = GTK_RANGE(m_widget);
319 return ( (window == GTK_WIDGET(range)->window) ||
320 (window == range->trough) ||
f03fc89f
VZ
321 (window == range->slider) ||
322 (window == range->step_forw) ||
323 (window == range->step_back) );
b4071e91 324}
58614078
RR
325
326void wxScrollBar::ApplyWidgetStyle()
327{
2d17d68f
RR
328 SetWidgetStyle();
329 gtk_widget_set_style( m_widget, m_widgetStyle );
58614078
RR
330}
331
dcf924a3 332#endif