]> git.saurik.com Git - wxWidgets.git/blob - src/gtk/scrolwin.cpp
merging back XTI branch part 2
[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 // For compilers that support precompilation, includes "wx.h".
14 #include "wx/wxprec.h"
15
16 #ifdef __BORLANDC__
17 #pragma hdrstop
18 #endif
19
20 #include "wx/scrolwin.h"
21
22 #include <gtk/gtk.h>
23
24 // ----------------------------------------------------------------------------
25 // wxScrollHelper implementation
26 // ----------------------------------------------------------------------------
27
28 void wxScrollHelper::SetScrollbars(int pixelsPerUnitX, int pixelsPerUnitY,
29 int noUnitsX, int noUnitsY,
30 int xPos, int yPos,
31 bool noRefresh)
32 {
33 m_win->m_scrollPos[wxWindow::ScrollDir_Horz] =
34 m_win->m_scrollBar[wxWindow::ScrollDir_Horz]->adjustment->value = xPos;
35 m_win->m_scrollPos[wxWindow::ScrollDir_Vert] =
36 m_win->m_scrollBar[wxWindow::ScrollDir_Vert]->adjustment->value = yPos;
37 base_type::SetScrollbars(
38 pixelsPerUnitX, pixelsPerUnitY, noUnitsX, noUnitsY, xPos, yPos, noRefresh);
39 }
40
41 void wxScrollHelper::DoAdjustScrollbar(GtkRange* range,
42 int pixelsPerLine,
43 int winSize,
44 int virtSize,
45 int *pos,
46 int *lines,
47 int *linesPerPage)
48 {
49 if (!range)
50 return;
51
52 int upper;
53 int page_size;
54 if (pixelsPerLine > 0 && winSize > 0 && winSize < virtSize)
55 {
56 upper = (virtSize + pixelsPerLine - 1) / pixelsPerLine;
57 page_size = winSize / pixelsPerLine;
58 *lines = upper;
59 *linesPerPage = page_size;
60 }
61 else
62 {
63 // GtkRange won't allow upper == lower, so for disabled state use [0,1]
64 // with a page size of 1. This will also clamp position to 0.
65 upper = 1;
66 page_size = 1;
67 *lines = 0;
68 *linesPerPage = 0;
69 }
70
71 GtkAdjustment* adj = range->adjustment;
72 adj->step_increment = 1;
73 adj->page_increment =
74 adj->page_size = page_size;
75 gtk_range_set_range(range, 0, upper);
76
77 // ensure that the scroll position is always in valid range
78 if (*pos > *lines)
79 *pos = *lines;
80 }
81
82 void wxScrollHelper::AdjustScrollbars()
83 {
84 int vw, vh;
85 m_targetWindow->GetVirtualSize(&vw, &vh);
86
87 int w, h;
88 const wxSize availSize = GetSizeAvailableForScrollTarget(
89 m_win->GetSize() - m_win->GetWindowBorderSize());
90 if ( availSize.x >= vw && availSize.y >= vh )
91 {
92 w = availSize.x;
93 h = availSize.y;
94
95 // we know that the scrollbars will be removed
96 DoAdjustHScrollbar(w, vw);
97 DoAdjustVScrollbar(h, vh);
98
99 return;
100 }
101
102 m_targetWindow->GetClientSize(&w, NULL);
103 DoAdjustHScrollbar(w, vw);
104
105 m_targetWindow->GetClientSize(NULL, &h);
106 DoAdjustVScrollbar(h, vh);
107
108 const int w_old = w;
109 m_targetWindow->GetClientSize(&w, NULL);
110 if ( w != w_old )
111 {
112 // It is necessary to repeat the calculations in this case to avoid an
113 // observed infinite series of size events, involving alternating
114 // changes in visibility of the scrollbars.
115 // At this point, GTK+ has already queued a resize, which will cause
116 // AdjustScrollbars() to be called again. If the scrollbar visibility
117 // is not correct before then, yet another resize will occur, possibly
118 // leading to an unending series if the sizes are just right.
119 DoAdjustHScrollbar(w, vw);
120
121 m_targetWindow->GetClientSize(NULL, &h);
122 DoAdjustVScrollbar(h, vh);
123 }
124 }
125
126 void wxScrollHelper::DoScrollOneDir(int orient,
127 int pos,
128 int pixelsPerLine,
129 int *posOld)
130 {
131 if ( pos != -1 && pos != *posOld && pixelsPerLine )
132 {
133 m_win->SetScrollPos(orient, pos);
134 pos = m_win->GetScrollPos(orient);
135
136 int diff = (*posOld - pos)*pixelsPerLine;
137 m_targetWindow->ScrollWindow(orient == wxHORIZONTAL ? diff : 0,
138 orient == wxHORIZONTAL ? 0 : diff);
139
140 *posOld = pos;
141 }
142 }
143
144 void wxScrollHelper::DoScroll( int x_pos, int y_pos )
145 {
146 wxCHECK_RET( m_targetWindow != 0, wxT("No target window") );
147
148 DoScrollOneDir(wxHORIZONTAL, x_pos, m_xScrollPixelsPerLine, &m_xScrollPosition);
149 DoScrollOneDir(wxVERTICAL, y_pos, m_yScrollPixelsPerLine, &m_yScrollPosition);
150 }
151
152 // ----------------------------------------------------------------------------
153 // scrollbars visibility
154 // ----------------------------------------------------------------------------
155
156 namespace
157 {
158
159 GtkPolicyType GtkPolicyFromWX(wxScrollbarVisibility visibility)
160 {
161 GtkPolicyType policy;
162 switch ( visibility )
163 {
164 case wxSHOW_SB_NEVER:
165 policy = GTK_POLICY_NEVER;
166 break;
167
168 case wxSHOW_SB_DEFAULT:
169 policy = GTK_POLICY_AUTOMATIC;
170 break;
171
172 default:
173 wxFAIL_MSG( wxS("unknown scrollbar visibility") );
174 // fall through
175
176 case wxSHOW_SB_ALWAYS:
177 policy = GTK_POLICY_ALWAYS;
178 break;
179 }
180
181 return policy;
182 }
183
184 } // anonymous namespace
185
186 void wxScrollHelper::DoShowScrollbars(wxScrollbarVisibility horz,
187 wxScrollbarVisibility vert)
188 {
189 GtkScrolledWindow * const scrolled = GTK_SCROLLED_WINDOW(m_win->m_widget);
190 wxCHECK_RET( scrolled, "window must be created" );
191
192 gtk_scrolled_window_set_policy(scrolled,
193 GtkPolicyFromWX(horz),
194 GtkPolicyFromWX(vert));
195 }