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