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: scrolwin.cpp 37063 2006-01-23 01:14:32Z MR $
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/gtk1/private.h"
30 
31 // ============================================================================
32 // implementation
33 // ============================================================================
34 
35 // ----------------------------------------------------------------------------
36 // wxScrollHelper implementation
37 // ----------------------------------------------------------------------------
38 
SetScrollbars(int pixelsPerUnitX,int pixelsPerUnitY,int noUnitsX,int noUnitsY,int xPos,int yPos,bool noRefresh)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_hAdjust->value = m_xScrollPosition = xPos;
54     m_win->m_vAdjust->value = m_yScrollPosition = yPos;
55 
56     // Setting hints here should arguably be deprecated, but without it
57     // a sizer might override this manual scrollbar setting in old code.
58     // m_targetWindow->SetVirtualSizeHints( noUnitsX * pixelsPerUnitX, noUnitsY * pixelsPerUnitY );
59 
60     int w = noUnitsX * pixelsPerUnitX;
61     int h = noUnitsY * pixelsPerUnitY;
62     m_targetWindow->SetVirtualSize( w ? w : wxDefaultCoord,
63                                     h ? h : wxDefaultCoord);
64 
65     if (!noRefresh)
66     {
67         int new_x = m_xScrollPixelsPerLine * m_xScrollPosition;
68         int new_y = m_yScrollPixelsPerLine * m_yScrollPosition;
69 
70         m_targetWindow->ScrollWindow( old_x - new_x, old_y - new_y );
71     }
72 
73     m_targetWindow->m_hasScrolling = pixelsPerUnitX || pixelsPerUnitY;
74 }
75 
DoAdjustScrollbar(GtkAdjustment * adj,int pixelsPerLine,int winSize,int virtSize,int * pos,int * lines,int * linesPerPage)76 void wxScrollHelperNative::DoAdjustScrollbar(GtkAdjustment *adj,
77                                              int pixelsPerLine,
78                                              int winSize,
79                                              int virtSize,
80                                              int *pos,
81                                              int *lines,
82                                              int *linesPerPage)
83 {
84     if ( pixelsPerLine == 0 )
85     {
86         adj->upper = 1.0;
87         adj->page_increment = 1.0;
88         adj->page_size = 1.0;
89     }
90     else // we do have scrollbar
91     {
92         adj->upper = (virtSize + pixelsPerLine - 1) / pixelsPerLine;
93         adj->page_size = winSize / pixelsPerLine;
94         adj->page_increment = winSize / pixelsPerLine;
95 
96         // Special case. When client and virtual size are very close but
97         // the client is big enough, kill scrollbar.
98 
99         if ((adj->page_size < adj->upper) && (winSize >= virtSize))
100             adj->page_size += 1.0;
101 
102         // If the scrollbar hits the right side, move the window
103         // right to keep it from over extending.
104 
105         if ( !wxIsNullDouble(adj->value) &&
106                 (adj->value + adj->page_size > adj->upper) )
107         {
108             adj->value = adj->upper - adj->page_size;
109             if (adj->value < 0.0)
110                 adj->value = 0.0;
111 
112             if ( m_win->GetChildren().empty() )
113             {
114                 // This is enough without child windows
115                 *pos = (int)adj->value;
116             }
117             else
118             {
119                 // We need to actually scroll window
120                 gtk_signal_emit_by_name( GTK_OBJECT(adj), "value_changed" );
121             }
122         }
123     }
124 
125     *lines = (int)(adj->upper + 0.5);
126     *linesPerPage = (int)(adj->page_increment + 0.5);
127     gtk_signal_emit_by_name( GTK_OBJECT(adj), "changed" );
128 }
129 
AdjustScrollbars()130 void wxScrollHelperNative::AdjustScrollbars()
131 {
132     int w, h;
133     int vw, vh;
134 
135     m_targetWindow->GetClientSize( &w, &h );
136     m_targetWindow->GetVirtualSize( &vw, &vh );
137 
138     DoAdjustScrollbar(m_win->m_hAdjust, m_xScrollPixelsPerLine, w, vw,
139                       &m_xScrollPosition, &m_xScrollLines, &m_xScrollLinesPerPage);
140     DoAdjustScrollbar(m_win->m_vAdjust, m_yScrollPixelsPerLine, h, vh,
141                       &m_yScrollPosition, &m_yScrollLines, &m_yScrollLinesPerPage);
142 }
143 
DoScroll(int orient,GtkAdjustment * adj,int pos,int pixelsPerLine,int * posOld)144 void wxScrollHelperNative::DoScroll(int orient,
145                                     GtkAdjustment *adj,
146                                     int pos,
147                                     int pixelsPerLine,
148                                     int *posOld)
149 {
150     if ( pos != -1 && pos != *posOld && pixelsPerLine )
151     {
152         int max = (int)(adj->upper - adj->page_size + 0.5);
153         if (max < 0)
154             max = 0;
155         if (pos > max)
156             pos = max;
157         if (pos < 0)
158             pos = 0;
159 
160         adj->value = pos;
161 
162         int diff = (*posOld - pos)*pixelsPerLine;
163         m_targetWindow->ScrollWindow(orient == wxHORIZONTAL ? diff : 0,
164                                      orient == wxHORIZONTAL ? 0 : diff);
165 
166         *posOld = pos;
167 
168         m_win->GtkUpdateScrollbar(orient);
169     }
170 }
171 
Scroll(int x_pos,int y_pos)172 void wxScrollHelperNative::Scroll( int x_pos, int y_pos )
173 {
174     wxCHECK_RET( m_targetWindow != 0, _T("No target window") );
175 
176     DoScroll(wxHORIZONTAL, m_win->m_hAdjust, x_pos, m_xScrollPixelsPerLine,
177                 &m_xScrollPosition);
178     DoScroll(wxVERTICAL, m_win->m_vAdjust, y_pos, m_yScrollPixelsPerLine,
179                 &m_yScrollPosition);
180 }
181 
182