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