Branch data Line data Source code
1 : : /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 : : /*************************************************************************
3 : : *
4 : : * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
5 : : *
6 : : * Copyright 2000, 2010 Oracle and/or its affiliates.
7 : : *
8 : : * OpenOffice.org - a multi-platform office productivity suite
9 : : *
10 : : * This file is part of OpenOffice.org.
11 : : *
12 : : * OpenOffice.org is free software: you can redistribute it and/or modify
13 : : * it under the terms of the GNU Lesser General Public License version 3
14 : : * only, as published by the Free Software Foundation.
15 : : *
16 : : * OpenOffice.org is distributed in the hope that it will be useful,
17 : : * but WITHOUT ANY WARRANTY; without even the implied warranty of
18 : : * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19 : : * GNU Lesser General Public License version 3 for more details
20 : : * (a copy is included in the LICENSE file that accompanied this code).
21 : : *
22 : : * You should have received a copy of the GNU Lesser General Public License
23 : : * version 3 along with OpenOffice.org. If not, see
24 : : * <http://www.openoffice.org/license.html>
25 : : * for a copy of the LGPLv3 License.
26 : : *
27 : : ************************************************************************/
28 : :
29 : :
30 : : #define _SVT_SCRWIN_CXX
31 : : #include <svtools/scrwin.hxx>
32 : :
33 : : //===================================================================
34 : :
35 : 34 : void ScrollableWindow::ImpInitialize( ScrollableWindowFlags nFlags )
36 : : {
37 : 34 : bHandleDragging = (sal_Bool) ( nFlags & SCRWIN_THUMBDRAGGING );
38 : 34 : bVCenter = (nFlags & SCRWIN_VCENTER) == SCRWIN_VCENTER;
39 : 34 : bHCenter = (nFlags & SCRWIN_HCENTER) == SCRWIN_HCENTER;
40 : 34 : bScrolling = sal_False;
41 : :
42 : : // set the handlers for the scrollbars
43 : 34 : aVScroll.SetScrollHdl( LINK(this, ScrollableWindow, ScrollHdl) );
44 : 34 : aHScroll.SetScrollHdl( LINK(this, ScrollableWindow, ScrollHdl) );
45 : 34 : aVScroll.SetEndScrollHdl( LINK(this, ScrollableWindow, EndScrollHdl) );
46 : 34 : aHScroll.SetEndScrollHdl( LINK(this, ScrollableWindow, EndScrollHdl) );
47 : :
48 : 34 : nColumnPixW = nLinePixH = GetSettings().GetStyleSettings().GetScrollBarSize();
49 : 34 : }
50 : :
51 : : //-------------------------------------------------------------------
52 : :
53 : 34 : ScrollableWindow::ScrollableWindow( Window* pParent, WinBits nBits,
54 : : ScrollableWindowFlags nFlags ) :
55 : : Window( pParent, WinBits(nBits|WB_CLIPCHILDREN) ),
56 : : aVScroll( this, WinBits(WB_VSCROLL | WB_DRAG) ),
57 : : aHScroll( this, WinBits(WB_HSCROLL | WB_DRAG) ),
58 [ + - ][ + - ]: 34 : aCornerWin( this )
[ + - ]
59 : : {
60 [ + - ]: 34 : ImpInitialize( nFlags );
61 : 34 : }
62 : :
63 : : // -----------------------------------------------------------------------
64 : :
65 : 0 : void ScrollableWindow::Command( const CommandEvent& rCEvt )
66 : : {
67 [ # # # # : 0 : if ( (rCEvt.GetCommand() == COMMAND_WHEEL) ||
# # ][ # # ]
68 : 0 : (rCEvt.GetCommand() == COMMAND_STARTAUTOSCROLL) ||
69 : 0 : (rCEvt.GetCommand() == COMMAND_AUTOSCROLL) )
70 : : {
71 : : ScrollBar* pHScrBar;
72 : : ScrollBar* pVScrBar;
73 [ # # ]: 0 : if ( aHScroll.IsVisible() )
74 : 0 : pHScrBar = &aHScroll;
75 : : else
76 : 0 : pHScrBar = NULL;
77 [ # # ]: 0 : if ( aVScroll.IsVisible() )
78 : 0 : pVScrBar = &aVScroll;
79 : : else
80 : 0 : pVScrBar = NULL;
81 [ # # ]: 0 : if ( HandleScrollCommand( rCEvt, pHScrBar, pVScrBar ) )
82 : 0 : return;
83 : : }
84 : :
85 : 0 : Window::Command( rCEvt );
86 : : }
87 : :
88 : : //-------------------------------------------------------------------
89 : :
90 : 0 : void ScrollableWindow::DataChanged( const DataChangedEvent& rDCEvt )
91 : : {
92 [ # # # # ]: 0 : if ( (rDCEvt.GetType() == DATACHANGED_SETTINGS) &&
[ # # ]
93 : 0 : (rDCEvt.GetFlags() & SETTINGS_STYLE) )
94 : : {
95 : 0 : Resize();
96 : 0 : Invalidate();
97 : : }
98 : :
99 : 0 : Window::DataChanged( rDCEvt );
100 : 0 : }
101 : :
102 : : //-------------------------------------------------------------------
103 : :
104 : 0 : Size ScrollableWindow::GetOutputSizePixel() const
105 : : {
106 : 0 : Size aSz( Window::GetOutputSizePixel() );
107 : :
108 : 0 : long nTmp = GetSettings().GetStyleSettings().GetScrollBarSize();
109 [ # # ]: 0 : if ( aHScroll.IsVisible() )
110 : 0 : aSz.Height() -= nTmp;
111 [ # # ]: 0 : if ( aVScroll.IsVisible() )
112 : 0 : aSz.Width() -= nTmp;
113 : 0 : return aSz;
114 : : }
115 : :
116 : : //-------------------------------------------------------------------
117 : :
118 : 0 : IMPL_LINK( ScrollableWindow, EndScrollHdl, ScrollBar *, pScroll )
119 : : {
120 : : // notify the start of scrolling, if not already scrolling
121 [ # # ]: 0 : if ( !bScrolling )
122 [ # # ]: 0 : StartScroll(), bScrolling = sal_True;
123 : :
124 : : // get the delta in logic coordinates
125 [ # # ]: 0 : Size aDelta( PixelToLogic( Size( aHScroll.GetDelta(), aVScroll.GetDelta() ) ) );
126 : :
127 : : // scroll the window, if this is not already done
128 [ # # ]: 0 : if ( !bHandleDragging )
129 : : {
130 [ # # ]: 0 : if ( pScroll == &aHScroll )
131 [ # # ]: 0 : Scroll( aDelta.Width(), 0 );
132 : : else
133 [ # # ]: 0 : Scroll( 0, aDelta.Height() );
134 : : }
135 : :
136 : : // notify the end of scrolling
137 : 0 : bScrolling = sal_False;
138 [ # # ]: 0 : EndScroll( aDelta.Width(), aDelta.Height() );
139 : 0 : return 0;
140 : : }
141 : :
142 : : //-------------------------------------------------------------------
143 : :
144 : 0 : IMPL_LINK( ScrollableWindow, ScrollHdl, ScrollBar *, pScroll )
145 : : {
146 : : // notify the start of scrolling, if not already scrolling
147 [ # # ]: 0 : if ( !bScrolling )
148 : 0 : StartScroll(), bScrolling = sal_True;
149 : :
150 [ # # ]: 0 : if ( bHandleDragging )
151 : : {
152 : : // get the delta in logic coordinates
153 : : Size aDelta( PixelToLogic(
154 [ # # ]: 0 : Size( aHScroll.GetDelta(), aVScroll.GetDelta() ) ) );
155 [ # # ]: 0 : if ( pScroll == &aHScroll )
156 [ # # ]: 0 : Scroll( aDelta.Width(), 0 );
157 : : else
158 [ # # ]: 0 : Scroll( 0, aDelta.Height() );
159 : : }
160 : 0 : return 0;
161 : : }
162 : :
163 : : //-------------------------------------------------------------------
164 : :
165 : 109 : void ScrollableWindow::Resize()
166 : : {
167 : : // get the new output-size in pixel
168 : 109 : Size aOutPixSz = Window::GetOutputSizePixel();
169 : :
170 : : // determine the size of the output-area and if we need scrollbars
171 : 109 : const long nScrSize = GetSettings().GetStyleSettings().GetScrollBarSize();
172 : 109 : sal_Bool bVVisible = sal_False; // by default no vertical-ScrollBar
173 : 109 : sal_Bool bHVisible = sal_False; // by default no horizontal-ScrollBar
174 : : sal_Bool bChanged; // determines if a visiblility was changed
175 [ + + ]: 177 : do
176 : : {
177 : 177 : bChanged = sal_False;
178 : :
179 : : // does we need a vertical ScrollBar
180 [ + + ][ + + ]: 177 : if ( aOutPixSz.Width() < aTotPixSz.Width() && !bHVisible )
[ + + ]
181 : 68 : { bHVisible = sal_True;
182 : 68 : aOutPixSz.Height() -= nScrSize;
183 : 68 : bChanged = sal_True;
184 : : }
185 : :
186 : : // does we need a horizontal ScrollBar
187 [ + + ][ + + ]: 177 : if ( aOutPixSz.Height() < aTotPixSz.Height() && !bVVisible )
[ + + ]
188 : 68 : { bVVisible = sal_True;
189 : 68 : aOutPixSz.Width() -= nScrSize;
190 : 68 : bChanged = sal_True;
191 : : }
192 : :
193 : : }
194 : : while ( bChanged ); // until no visibility has changed
195 : :
196 : : // store the old offset and map-mode
197 [ + - ]: 109 : MapMode aMap( GetMapMode() );
198 : 109 : Point aOldPixOffset( aPixOffset );
199 : :
200 : : // justify (right/bottom borders should never exceed the virtual window)
201 : 109 : Size aPixDelta;
202 [ - + ]: 109 : if ( aPixOffset.X() < 0 &&
[ - + # # ]
203 : 0 : aPixOffset.X() + aTotPixSz.Width() < aOutPixSz.Width() )
204 : 0 : aPixDelta.Width() =
205 : 0 : aOutPixSz.Width() - ( aPixOffset.X() + aTotPixSz.Width() );
206 [ - + # # ]: 109 : if ( aPixOffset.Y() < 0 &&
[ - + ]
207 : 0 : aPixOffset.Y() + aTotPixSz.Height() < aOutPixSz.Height() )
208 : 0 : aPixDelta.Height() =
209 : 0 : aOutPixSz.Height() - ( aPixOffset.Y() + aTotPixSz.Height() );
210 [ + - ][ - + ]: 109 : if ( aPixDelta.Width() || aPixDelta.Height() )
[ - + ]
211 : : {
212 : 0 : aPixOffset.X() += aPixDelta.Width();
213 : 0 : aPixOffset.Y() += aPixDelta.Height();
214 : : }
215 : :
216 : : // for axis without scrollbar restore the origin
217 [ + + ][ - + ]: 109 : if ( !bVVisible || !bHVisible )
218 : : {
219 : : aPixOffset = Point(
220 : : bHVisible
221 : 0 : ? aPixOffset.X()
222 : : : ( bHCenter
223 : 41 : ? (aOutPixSz.Width()-aTotPixSz.Width()) / 2
224 : : : 0 ),
225 : : bVVisible
226 : 0 : ? aPixOffset.Y()
227 : : : ( bVCenter
228 : 41 : ? (aOutPixSz.Height()-aTotPixSz.Height()) / 2
229 [ - + ][ + - ]: 123 : : 0 ) );
[ - + ][ + - ]
230 : : }
231 [ + + ][ + - ]: 109 : if ( bHVisible && !aHScroll.IsVisible() )
[ + + ][ + + ]
232 : 34 : aPixOffset.X() = 0;
233 [ + + ][ + - ]: 109 : if ( bVVisible && !aVScroll.IsVisible() )
[ + + ][ + + ]
234 : 34 : aPixOffset.Y() = 0;
235 : :
236 : : // select the shifted map-mode
237 [ + + ]: 109 : if ( aPixOffset != aOldPixOffset )
238 : : {
239 [ + - ][ + - ]: 41 : Window::SetMapMode( MapMode( MAP_PIXEL ) );
[ + - ]
240 : : Window::Scroll(
241 : 41 : aPixOffset.X() - aOldPixOffset.X(),
242 [ + - ]: 82 : aPixOffset.Y() - aOldPixOffset.Y() );
243 [ + - ]: 41 : SetMapMode( aMap );
244 : : }
245 : :
246 : : // show or hide scrollbars
247 [ + - ]: 109 : aVScroll.Show( bVVisible );
248 [ + - ]: 109 : aHScroll.Show( bHVisible );
249 : :
250 : : // disable painting in the corner between the scrollbars
251 [ + + ][ + - ]: 109 : if ( bVVisible && bHVisible )
252 : : {
253 : 68 : aCornerWin.SetPosSizePixel(Point(aOutPixSz.Width(), aOutPixSz.Height()),
254 [ + - ]: 136 : Size(nScrSize, nScrSize) );
255 [ + - ]: 68 : aCornerWin.Show();
256 : : }
257 : : else
258 [ + - ]: 41 : aCornerWin.Hide();
259 : :
260 : : // resize scrollbars and set their ranges
261 [ + + ]: 109 : if ( bHVisible )
262 : : {
263 : : aHScroll.SetPosSizePixel(
264 : 68 : Point( 0, aOutPixSz.Height() ),
265 [ + - ]: 136 : Size( aOutPixSz.Width(), nScrSize ) );
266 [ + - ]: 68 : aHScroll.SetRange( Range( 0, aTotPixSz.Width() ) );
267 : 68 : aHScroll.SetPageSize( aOutPixSz.Width() );
268 [ + - ]: 68 : aHScroll.SetVisibleSize( aOutPixSz.Width() );
269 : 68 : aHScroll.SetLineSize( nColumnPixW );
270 [ + - ]: 68 : aHScroll.SetThumbPos( -aPixOffset.X() );
271 : : }
272 [ + + ]: 109 : if ( bVVisible )
273 : : {
274 : : aVScroll.SetPosSizePixel(
275 : 68 : Point( aOutPixSz.Width(), 0 ),
276 [ + - ]: 136 : Size( nScrSize,aOutPixSz.Height() ) );
277 [ + - ]: 68 : aVScroll.SetRange( Range( 0, aTotPixSz.Height() ) );
278 : 68 : aVScroll.SetPageSize( aOutPixSz.Height() );
279 [ + - ]: 68 : aVScroll.SetVisibleSize( aOutPixSz.Height() );
280 : 68 : aVScroll.SetLineSize( nLinePixH );
281 [ + - ]: 68 : aVScroll.SetThumbPos( -aPixOffset.Y() );
282 [ + - ]: 109 : }
283 : 109 : }
284 : :
285 : : //-------------------------------------------------------------------
286 : :
287 : 0 : void ScrollableWindow::StartScroll()
288 : : {
289 : 0 : }
290 : :
291 : : //-------------------------------------------------------------------
292 : :
293 : 0 : void ScrollableWindow::EndScroll( long, long )
294 : : {
295 : 0 : }
296 : :
297 : : //-------------------------------------------------------------------
298 : :
299 : 118 : void ScrollableWindow::SetMapMode( const MapMode& rNewMapMode )
300 : : {
301 [ + - ]: 118 : MapMode aMap( rNewMapMode );
302 [ + - ][ + - ]: 118 : aMap.SetOrigin( aMap.GetOrigin() + PixelToLogic( aPixOffset, aMap ) );
303 [ + - ][ + - ]: 118 : Window::SetMapMode( aMap );
304 : 118 : }
305 : :
306 : : //-------------------------------------------------------------------
307 : :
308 : 109 : MapMode ScrollableWindow::GetMapMode() const
309 : : {
310 : 109 : MapMode aMap( Window::GetMapMode() );
311 [ + - ][ + - ]: 109 : aMap.SetOrigin( aMap.GetOrigin() - PixelToLogic( aPixOffset ) );
312 : 109 : return aMap;
313 : : }
314 : :
315 : : //-------------------------------------------------------------------
316 : :
317 : 41 : void ScrollableWindow::SetTotalSize( const Size& rNewSize )
318 : : {
319 : 41 : aTotPixSz = LogicToPixel( rNewSize );
320 : 41 : ScrollableWindow::Resize();
321 : 41 : }
322 : :
323 : : //-------------------------------------------------------------------
324 : :
325 : 0 : void ScrollableWindow::Scroll( long nDeltaX, long nDeltaY, sal_uInt16 )
326 : : {
327 [ # # ]: 0 : if ( !bScrolling )
328 [ # # ]: 0 : StartScroll();
329 : :
330 : : // get the delta in pixel
331 [ # # ]: 0 : Size aDeltaPix( LogicToPixel( Size(nDeltaX, nDeltaY) ) );
332 [ # # ]: 0 : Size aOutPixSz( GetOutputSizePixel() );
333 [ # # ]: 0 : MapMode aMap( GetMapMode() );
334 : 0 : Point aNewPixOffset( aPixOffset );
335 : :
336 : : // scrolling horizontally?
337 [ # # ]: 0 : if ( nDeltaX != 0 )
338 : : {
339 : 0 : aNewPixOffset.X() -= aDeltaPix.Width();
340 [ # # ]: 0 : if ( ( aOutPixSz.Width() - aNewPixOffset.X() ) > aTotPixSz.Width() )
341 : 0 : aNewPixOffset.X() = - ( aTotPixSz.Width() - aOutPixSz.Width() );
342 [ # # ]: 0 : else if ( aNewPixOffset.X() > 0 )
343 : 0 : aNewPixOffset.X() = 0;
344 : : }
345 : :
346 : : // scrolling vertically?
347 [ # # ]: 0 : if ( nDeltaY != 0 )
348 : : {
349 : 0 : aNewPixOffset.Y() -= aDeltaPix.Height();
350 [ # # ]: 0 : if ( ( aOutPixSz.Height() - aNewPixOffset.Y() ) > aTotPixSz.Height() )
351 : 0 : aNewPixOffset.Y() = - ( aTotPixSz.Height() - aOutPixSz.Height() );
352 [ # # ]: 0 : else if ( aNewPixOffset.Y() > 0 )
353 : 0 : aNewPixOffset.Y() = 0;
354 : : }
355 : :
356 : : // recompute the logical scroll units
357 : 0 : aDeltaPix.Width() = aPixOffset.X() - aNewPixOffset.X();
358 : 0 : aDeltaPix.Height() = aPixOffset.Y() - aNewPixOffset.Y();
359 [ # # ]: 0 : Size aDelta( PixelToLogic(aDeltaPix) );
360 : 0 : nDeltaX = aDelta.Width();
361 : 0 : nDeltaY = aDelta.Height();
362 : 0 : aPixOffset = aNewPixOffset;
363 : :
364 : : // scrolling?
365 [ # # ][ # # ]: 0 : if ( nDeltaX != 0 || nDeltaY != 0 )
366 : : {
367 [ # # ]: 0 : Update();
368 : :
369 : : // does the new area overlap the old one?
370 [ # # # # ]: 0 : if ( Abs( (int)aDeltaPix.Height() ) < aOutPixSz.Height() ||
[ # # ]
371 : 0 : Abs( (int)aDeltaPix.Width() ) < aOutPixSz.Width() )
372 : : {
373 : : // scroll the overlapping area
374 [ # # ]: 0 : SetMapMode( aMap );
375 : :
376 : : // never scroll the scrollbars itself!
377 : : Window::Scroll(-nDeltaX, -nDeltaY,
378 [ # # ][ # # ]: 0 : PixelToLogic( Rectangle( Point(0, 0), aOutPixSz ) ) );
[ # # ]
379 : : }
380 : : else
381 : : {
382 : : // repaint all
383 [ # # ]: 0 : SetMapMode( aMap );
384 [ # # ]: 0 : Invalidate();
385 : : }
386 : :
387 [ # # ]: 0 : Update();
388 : : }
389 : :
390 [ # # ]: 0 : if ( !bScrolling )
391 : : {
392 [ # # ]: 0 : EndScroll( nDeltaX, nDeltaY );
393 [ # # ]: 0 : if ( nDeltaX )
394 [ # # ]: 0 : aHScroll.SetThumbPos( -aPixOffset.X() );
395 [ # # ]: 0 : if ( nDeltaY )
396 [ # # ]: 0 : aVScroll.SetThumbPos( -aPixOffset.Y() );
397 [ # # ]: 0 : }
398 : 0 : }
399 : :
400 : :
401 : : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
|