]> git.saurik.com Git - wxWidgets.git/blame - src/gtk/scrolwin.cpp
Fix crash in wxDC::GetMultiLineTextExtent() after last commit.
[wxWidgets.git] / src / gtk / scrolwin.cpp
CommitLineData
30954328 1/////////////////////////////////////////////////////////////////////////////
80fdcdb9 2// Name: src/gtk/scrolwin.cpp
30954328 3// Purpose: wxScrolledWindow implementation
47a3ff38 4// Author: Robert Roebling
566d84a7 5// Modified by: Ron Lee
d32e78bd 6// Vadim Zeitlin: removed 90% of duplicated common code
30954328
RR
7// Created: 01/02/97
8// RCS-ID: $Id$
47a3ff38 9// Copyright: (c) Robert Roebling
65571936 10// Licence: wxWindows licence
30954328
RR
11/////////////////////////////////////////////////////////////////////////////
12
30954328
RR
13// For compilers that support precompilation, includes "wx.h".
14#include "wx/wxprec.h"
15
16#ifdef __BORLANDC__
17 #pragma hdrstop
18#endif
19
e1bf3ad3 20#include "wx/scrolwin.h"
30954328 21
8aa40b04 22#include <gtk/gtk.h>
385e8575 23#include "wx/gtk/private/gtk2-compat.h"
30954328 24
30954328 25// ----------------------------------------------------------------------------
d32e78bd 26// wxScrollHelper implementation
30954328
RR
27// ----------------------------------------------------------------------------
28
29e1398f
VZ
29void wxScrollHelper::SetScrollbars(int pixelsPerUnitX, int pixelsPerUnitY,
30 int noUnitsX, int noUnitsY,
31 int xPos, int yPos,
8aa40b04 32 bool noRefresh)
30954328 33{
3ca5da93
PC
34 // prevent programmatic position changes from causing scroll events
35 m_win->SetScrollPos(wxHORIZONTAL, xPos);
36 m_win->SetScrollPos(wxVERTICAL, yPos);
37
8aa40b04
PC
38 base_type::SetScrollbars(
39 pixelsPerUnitX, pixelsPerUnitY, noUnitsX, noUnitsY, xPos, yPos, noRefresh);
30954328
RR
40}
41
29e1398f
VZ
42void wxScrollHelper::DoAdjustScrollbar(GtkRange* range,
43 int pixelsPerLine,
44 int winSize,
45 int virtSize,
46 int *pos,
47 int *lines,
48 int *linesPerPage)
30954328 49{
6d595f3d
JS
50 if (!range)
51 return;
52
f6814d01
PC
53 int upper;
54 int page_size;
fb18afdd 55 if (pixelsPerLine > 0 && winSize > 0 && winSize < virtSize)
4ca24f18 56 {
f6814d01
PC
57 upper = (virtSize + pixelsPerLine - 1) / pixelsPerLine;
58 page_size = winSize / pixelsPerLine;
5713b349
RR
59 *lines = upper;
60 *linesPerPage = page_size;
5713b349
RR
61 }
62 else
63 {
64 // GtkRange won't allow upper == lower, so for disabled state use [0,1]
65 // with a page size of 1. This will also clamp position to 0.
f6814d01
PC
66 upper = 1;
67 page_size = 1;
5713b349
RR
68 *lines = 0;
69 *linesPerPage = 0;
4ca24f18 70 }
9ec927f8 71
385e8575
PC
72 gtk_range_set_increments(range, 1, page_size);
73 gtk_adjustment_set_page_size(gtk_range_get_adjustment(range), page_size);
f6814d01 74 gtk_range_set_range(range, 0, upper);
ae4c09a8
PC
75
76 // ensure that the scroll position is always in valid range
77 if (*pos > *lines)
78 *pos = *lines;
30954328
RR
79}
80
29e1398f 81void wxScrollHelper::AdjustScrollbars()
566d84a7 82{
9ec927f8 83 int vw, vh;
3d9ecb87
VZ
84 m_targetWindow->GetVirtualSize(&vw, &vh);
85
86 int w, h;
87 const wxSize availSize = GetSizeAvailableForScrollTarget(
88 m_win->GetSize() - m_win->GetWindowBorderSize());
89 if ( availSize.x >= vw && availSize.y >= vh )
90 {
91 w = availSize.x;
92 h = availSize.y;
93
94 // we know that the scrollbars will be removed
95 DoAdjustHScrollbar(w, vw);
96 DoAdjustVScrollbar(h, vh);
97
98 return;
99 }
830ed6d9 100
cd38dd5b 101 m_targetWindow->GetClientSize(&w, NULL);
9ec927f8
VZ
102 DoAdjustHScrollbar(w, vw);
103
cd38dd5b 104 m_targetWindow->GetClientSize(NULL, &h);
9ec927f8 105 DoAdjustVScrollbar(h, vh);
cd38dd5b
PC
106
107 const int w_old = w;
108 m_targetWindow->GetClientSize(&w, NULL);
9ec927f8 109 if ( w != w_old )
cd38dd5b
PC
110 {
111 // It is necessary to repeat the calculations in this case to avoid an
112 // observed infinite series of size events, involving alternating
113 // changes in visibility of the scrollbars.
114 // At this point, GTK+ has already queued a resize, which will cause
115 // AdjustScrollbars() to be called again. If the scrollbar visibility
116 // is not correct before then, yet another resize will occur, possibly
117 // leading to an unending series if the sizes are just right.
9ec927f8
VZ
118 DoAdjustHScrollbar(w, vw);
119
cd38dd5b 120 m_targetWindow->GetClientSize(NULL, &h);
9ec927f8 121 DoAdjustVScrollbar(h, vh);
cd38dd5b 122 }
830ed6d9
RR
123}
124
29e1398f
VZ
125void wxScrollHelper::DoScrollOneDir(int orient,
126 int pos,
127 int pixelsPerLine,
128 int *posOld)
30486297 129{
d32e78bd 130 if ( pos != -1 && pos != *posOld && pixelsPerLine )
30486297 131 {
add7cadd
PC
132 m_win->SetScrollPos(orient, pos);
133 pos = m_win->GetScrollPos(orient);
30486297 134
d32e78bd
VZ
135 int diff = (*posOld - pos)*pixelsPerLine;
136 m_targetWindow->ScrollWindow(orient == wxHORIZONTAL ? diff : 0,
137 orient == wxHORIZONTAL ? 0 : diff);
30954328 138
d32e78bd 139 *posOld = pos;
2b5f62a0 140 }
30954328
RR
141}
142
29e1398f 143void wxScrollHelper::DoScroll( int x_pos, int y_pos )
30954328 144{
9a83f860 145 wxCHECK_RET( m_targetWindow != 0, wxT("No target window") );
30954328 146
0b0f6f87
VZ
147 DoScrollOneDir(wxHORIZONTAL, x_pos, m_xScrollPixelsPerLine, &m_xScrollPosition);
148 DoScrollOneDir(wxVERTICAL, y_pos, m_yScrollPixelsPerLine, &m_yScrollPosition);
30954328 149}
6362d82b
VZ
150
151// ----------------------------------------------------------------------------
152// scrollbars visibility
153// ----------------------------------------------------------------------------
154
155namespace
156{
157
158GtkPolicyType GtkPolicyFromWX(wxScrollbarVisibility visibility)
159{
160 GtkPolicyType policy;
161 switch ( visibility )
162 {
163 case wxSHOW_SB_NEVER:
164 policy = GTK_POLICY_NEVER;
165 break;
166
167 case wxSHOW_SB_DEFAULT:
168 policy = GTK_POLICY_AUTOMATIC;
169 break;
170
2805bdda
VZ
171 default:
172 wxFAIL_MSG( wxS("unknown scrollbar visibility") );
173 // fall through
174
6362d82b
VZ
175 case wxSHOW_SB_ALWAYS:
176 policy = GTK_POLICY_ALWAYS;
177 break;
178 }
179
180 return policy;
181}
182
183} // anonymous namespace
184
29e1398f
VZ
185void wxScrollHelper::DoShowScrollbars(wxScrollbarVisibility horz,
186 wxScrollbarVisibility vert)
6362d82b
VZ
187{
188 GtkScrolledWindow * const scrolled = GTK_SCROLLED_WINDOW(m_win->m_widget);
189 wxCHECK_RET( scrolled, "window must be created" );
190
191 gtk_scrolled_window_set_policy(scrolled,
192 GtkPolicyFromWX(horz),
193 GtkPolicyFromWX(vert));
194}