]> git.saurik.com Git - wxWidgets.git/blob - src/gtk/scrolwin.cpp
Make wxGTK's wxScrolledWindow set m_x/xScrollLines to 0
[wxWidgets.git] / src / gtk / scrolwin.cpp
1 /////////////////////////////////////////////////////////////////////////////
2 // Name: gtk/scrolwin.cpp
3 // Purpose: wxScrolledWindow implementation
4 // Author: Robert Roebling
5 // Modified by: Ron Lee
6 // Vadim Zeitlin: removed 90% of duplicated common code
7 // Created: 01/02/97
8 // RCS-ID: $Id$
9 // Copyright: (c) Robert Roebling
10 // Licence: wxWindows licence
11 /////////////////////////////////////////////////////////////////////////////
12
13 // ============================================================================
14 // declarations
15 // ============================================================================
16
17 // ----------------------------------------------------------------------------
18 // headers
19 // ----------------------------------------------------------------------------
20
21 // For compilers that support precompilation, includes "wx.h".
22 #include "wx/wxprec.h"
23
24 #ifdef __BORLANDC__
25 #pragma hdrstop
26 #endif
27
28 #include "wx/scrolwin.h"
29 #include "wx/gtk/private.h"
30
31 // ============================================================================
32 // implementation
33 // ============================================================================
34
35 // ----------------------------------------------------------------------------
36 // wxScrollHelper implementation
37 // ----------------------------------------------------------------------------
38
39 void wxScrollHelperNative::SetScrollbars(int pixelsPerUnitX, int pixelsPerUnitY,
40 int noUnitsX, int noUnitsY,
41 int xPos, int yPos,
42 bool noRefresh)
43 {
44 int xs, ys;
45 GetViewStart(& xs, & ys);
46
47 int old_x = m_xScrollPixelsPerLine * xs;
48 int old_y = m_yScrollPixelsPerLine * ys;
49
50 m_xScrollPixelsPerLine = pixelsPerUnitX;
51 m_yScrollPixelsPerLine = pixelsPerUnitY;
52
53 m_win->m_scrollBar[wxWindow::ScrollDir_Horz]->adjustment->value =
54 m_xScrollPosition = xPos;
55 m_win->m_scrollBar[wxWindow::ScrollDir_Vert]->adjustment->value =
56 m_yScrollPosition = yPos;
57
58 // Setting hints here should arguably be deprecated, but without it
59 // a sizer might override this manual scrollbar setting in old code.
60 // m_targetWindow->SetVirtualSizeHints( noUnitsX * pixelsPerUnitX, noUnitsY * pixelsPerUnitY );
61
62 int w = noUnitsX * pixelsPerUnitX;
63 int h = noUnitsY * pixelsPerUnitY;
64 m_targetWindow->SetVirtualSize( w ? w : wxDefaultCoord,
65 h ? h : wxDefaultCoord);
66
67 // If the target is not the same as the window with the scrollbars,
68 // then we need to update the scrollbars here, since they won't have
69 // been updated by SetVirtualSize().
70 if (m_targetWindow != m_win)
71 {
72 AdjustScrollbars();
73 }
74
75 if (!noRefresh)
76 {
77 int new_x = m_xScrollPixelsPerLine * m_xScrollPosition;
78 int new_y = m_yScrollPixelsPerLine * m_yScrollPosition;
79
80 m_targetWindow->ScrollWindow( old_x - new_x, old_y - new_y );
81 }
82 }
83
84 void wxScrollHelperNative::DoAdjustScrollbar(GtkRange* range,
85 int pixelsPerLine,
86 int winSize,
87 int virtSize,
88 int *lines,
89 int *linesPerPage)
90 {
91 if (pixelsPerLine > 0 && winSize > 0 && winSize < virtSize)
92 {
93 int upper = (virtSize + pixelsPerLine - 1) / pixelsPerLine;
94 int page_size = winSize / pixelsPerLine;
95
96 *lines = upper;
97 *linesPerPage = page_size;
98
99 GtkAdjustment* adj = range->adjustment;
100 adj->step_increment = 1;
101 adj->page_increment =
102 adj->page_size = page_size;
103 gtk_range_set_range(range, 0, upper);
104 }
105 else
106 {
107 // GtkRange won't allow upper == lower, so for disabled state use [0,1]
108 // with a page size of 1. This will also clamp position to 0.
109 int upper = 1;
110 int page_size = 1;
111
112 *lines = 0;
113 *linesPerPage = 0;
114
115 GtkAdjustment* adj = range->adjustment;
116 adj->step_increment = 1;
117 adj->page_increment =
118 adj->page_size = page_size;
119 gtk_range_set_range(range, 0, upper);
120 }
121 }
122
123 void wxScrollHelperNative::AdjustScrollbars()
124 {
125 int w, h;
126 int vw, vh;
127
128 m_targetWindow->m_hasScrolling = m_xScrollPixelsPerLine != 0 || m_yScrollPixelsPerLine != 0;
129
130 m_targetWindow->GetVirtualSize( &vw, &vh );
131
132 m_targetWindow->GetClientSize(&w, NULL);
133 DoAdjustScrollbar(
134 m_win->m_scrollBar[wxWindow::ScrollDir_Horz], m_xScrollPixelsPerLine,
135 w, vw, &m_xScrollLines, &m_xScrollLinesPerPage);
136 m_targetWindow->GetClientSize(NULL, &h);
137 DoAdjustScrollbar(
138 m_win->m_scrollBar[wxWindow::ScrollDir_Vert], m_yScrollPixelsPerLine,
139 h, vh, &m_yScrollLines, &m_yScrollLinesPerPage);
140
141 const int w_old = w;
142 m_targetWindow->GetClientSize(&w, NULL);
143 if (w != w_old)
144 {
145 // It is necessary to repeat the calculations in this case to avoid an
146 // observed infinite series of size events, involving alternating
147 // changes in visibility of the scrollbars.
148 // At this point, GTK+ has already queued a resize, which will cause
149 // AdjustScrollbars() to be called again. If the scrollbar visibility
150 // is not correct before then, yet another resize will occur, possibly
151 // leading to an unending series if the sizes are just right.
152 DoAdjustScrollbar(
153 m_win->m_scrollBar[wxWindow::ScrollDir_Horz], m_xScrollPixelsPerLine,
154 w, vw, &m_xScrollLines, &m_xScrollLinesPerPage);
155 m_targetWindow->GetClientSize(NULL, &h);
156 DoAdjustScrollbar(
157 m_win->m_scrollBar[wxWindow::ScrollDir_Vert], m_yScrollPixelsPerLine,
158 h, vh, &m_yScrollLines, &m_yScrollLinesPerPage);
159 }
160 }
161
162 void wxScrollHelperNative::DoScroll(int orient,
163 int pos,
164 int pixelsPerLine,
165 int *posOld)
166 {
167 if ( pos != -1 && pos != *posOld && pixelsPerLine )
168 {
169 m_win->SetScrollPos(orient, pos);
170 pos = m_win->GetScrollPos(orient);
171
172 int diff = (*posOld - pos)*pixelsPerLine;
173 m_targetWindow->ScrollWindow(orient == wxHORIZONTAL ? diff : 0,
174 orient == wxHORIZONTAL ? 0 : diff);
175
176 *posOld = pos;
177 }
178 }
179
180 void wxScrollHelperNative::Scroll( int x_pos, int y_pos )
181 {
182 wxCHECK_RET( m_targetWindow != 0, _T("No target window") );
183
184 DoScroll(wxHORIZONTAL, x_pos, m_xScrollPixelsPerLine, &m_xScrollPosition);
185 DoScroll(wxVERTICAL, y_pos, m_yScrollPixelsPerLine, &m_yScrollPosition);
186 }