Bump version to 21.06.18.1
[LibreOffice.git] / starmath / source / scrwin.cxx
blob596ed799424e3df72d66120dc3b0b421f1f96fb7
1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 /*
3 * This file is part of the LibreOffice project.
5 * This Source Code Form is subject to the terms of the Mozilla Public
6 * License, v. 2.0. If a copy of the MPL was not distributed with this
7 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
9 * This file incorporates work covered by the following license notice:
11 * Licensed to the Apache Software Foundation (ASF) under one or more
12 * contributor license agreements. See the NOTICE file distributed
13 * with this work for additional information regarding copyright
14 * ownership. The ASF licenses this file to you under the Apache
15 * License, Version 2.0 (the "License"); you may not use this file
16 * except in compliance with the License. You may obtain a copy of
17 * the License at http://www.apache.org/licenses/LICENSE-2.0 .
20 #include <vcl/commandevent.hxx>
21 #include <vcl/event.hxx>
22 #include <vcl/settings.hxx>
23 #include <vcl/scrbar.hxx>
24 #include <scrwin.hxx>
26 ScrollableWindow::ScrollableWindow( vcl::Window* pParent ) :
27 Window( pParent, WB_CLIPCHILDREN ),
28 aVScroll( VclPtr<ScrollBar>::Create(this, WinBits(WB_VSCROLL | WB_DRAG)) ),
29 aHScroll( VclPtr<ScrollBar>::Create(this, WinBits(WB_HSCROLL | WB_DRAG)) ),
30 aCornerWin( VclPtr<ScrollBarBox>::Create(this) )
32 bScrolling = false;
34 // set the handlers for the scrollbars
35 aVScroll->SetScrollHdl( LINK(this, ScrollableWindow, ScrollHdl) );
36 aHScroll->SetScrollHdl( LINK(this, ScrollableWindow, ScrollHdl) );
37 aVScroll->SetEndScrollHdl( LINK(this, ScrollableWindow, EndScrollHdl) );
38 aHScroll->SetEndScrollHdl( LINK(this, ScrollableWindow, EndScrollHdl) );
40 nColumnPixW = nLinePixH = GetSettings().GetStyleSettings().GetScrollBarSize();
44 ScrollableWindow::~ScrollableWindow()
46 disposeOnce();
49 void ScrollableWindow::dispose()
51 aVScroll.disposeAndClear();
52 aHScroll.disposeAndClear();
53 aCornerWin.disposeAndClear();
54 Window::dispose();
58 void ScrollableWindow::Command( const CommandEvent& rCEvt )
60 if ( (rCEvt.GetCommand() == CommandEventId::Wheel) ||
61 (rCEvt.GetCommand() == CommandEventId::StartAutoScroll) ||
62 (rCEvt.GetCommand() == CommandEventId::AutoScroll) )
64 ScrollBar* pHScrBar;
65 ScrollBar* pVScrBar;
66 if ( aHScroll->IsVisible() )
67 pHScrBar = aHScroll.get();
68 else
69 pHScrBar = nullptr;
70 if ( aVScroll->IsVisible() )
71 pVScrBar = aVScroll.get();
72 else
73 pVScrBar = nullptr;
74 if ( HandleScrollCommand( rCEvt, pHScrBar, pVScrBar ) )
75 return;
78 Window::Command( rCEvt );
82 void ScrollableWindow::DataChanged( const DataChangedEvent& rDCEvt )
84 if ( (rDCEvt.GetType() == DataChangedEventType::SETTINGS) &&
85 (rDCEvt.GetFlags() & AllSettingsFlags::STYLE) )
87 Resize();
88 Invalidate();
91 Window::DataChanged( rDCEvt );
95 Size ScrollableWindow::GetOutputSizePixel() const
97 Size aSz( Window::GetOutputSizePixel() );
99 tools::Long nTmp = GetSettings().GetStyleSettings().GetScrollBarSize();
100 if ( aHScroll->IsVisible() )
101 aSz.AdjustHeight( -nTmp );
102 if ( aVScroll->IsVisible() )
103 aSz.AdjustWidth( -nTmp );
104 return aSz;
108 IMPL_LINK( ScrollableWindow, EndScrollHdl, ScrollBar *, /*pScroll*/, void )
110 // notify the end of scrolling
111 bScrolling = false;
115 IMPL_LINK( ScrollableWindow, ScrollHdl, ScrollBar *, pScroll, void )
117 // notify the start of scrolling, if not already scrolling
118 if ( !bScrolling )
119 bScrolling = true;
121 // get the delta in logic coordinates
122 Size aDelta( PixelToLogic(
123 Size( aHScroll->GetDelta(), aVScroll->GetDelta() ) ) );
124 if ( pScroll == aHScroll.get() )
125 Scroll( aDelta.Width(), 0 );
126 else
127 Scroll( 0, aDelta.Height() );
131 void ScrollableWindow::Resize()
133 // get the new output-size in pixel
134 Size aOutPixSz = Window::GetOutputSizePixel();
136 // determine the size of the output-area and if we need scrollbars
137 const tools::Long nScrSize = GetSettings().GetStyleSettings().GetScrollBarSize();
138 bool bVVisible = false; // by default no vertical-ScrollBar
139 bool bHVisible = false; // by default no horizontal-ScrollBar
140 bool bChanged; // determines if a visiblility was changed
143 bChanged = false;
145 // does we need a vertical ScrollBar
146 if ( aOutPixSz.Width() < aTotPixSz.Width() && !bHVisible )
148 bHVisible = true;
149 aOutPixSz.AdjustHeight( -nScrSize );
150 bChanged = true;
153 // does we need a horizontal ScrollBar
154 if ( aOutPixSz.Height() < aTotPixSz.Height() && !bVVisible )
156 bVVisible = true;
157 aOutPixSz.AdjustWidth( -nScrSize );
158 bChanged = true;
162 while ( bChanged ); // until no visibility has changed
164 // store the old offset and map-mode
165 MapMode aMap( GetMapMode() );
166 Point aOldPixOffset( aPixOffset );
168 // justify (right/bottom borders should never exceed the virtual window)
169 Size aPixDelta;
170 if ( aPixOffset.X() < 0 &&
171 aPixOffset.X() + aTotPixSz.Width() < aOutPixSz.Width() )
172 aPixDelta.setWidth(
173 aOutPixSz.Width() - ( aPixOffset.X() + aTotPixSz.Width() ) );
174 if ( aPixOffset.Y() < 0 &&
175 aPixOffset.Y() + aTotPixSz.Height() < aOutPixSz.Height() )
176 aPixDelta.setHeight(
177 aOutPixSz.Height() - ( aPixOffset.Y() + aTotPixSz.Height() ) );
178 if ( aPixDelta.Width() || aPixDelta.Height() )
180 aPixOffset.AdjustX(aPixDelta.Width() );
181 aPixOffset.AdjustY(aPixDelta.Height() );
184 // for axis without scrollbar restore the origin
185 if ( !bVVisible || !bHVisible )
187 aPixOffset = Point(
188 bHVisible
189 ? aPixOffset.X()
190 : (aOutPixSz.Width()-aTotPixSz.Width()) / 2,
191 bVVisible
192 ? aPixOffset.Y()
193 : (aOutPixSz.Height()-aTotPixSz.Height()) / 2 );
195 if ( bHVisible && !aHScroll->IsVisible() )
196 aPixOffset.setX( 0 );
197 if ( bVVisible && !aVScroll->IsVisible() )
198 aPixOffset.setY( 0 );
200 // select the shifted map-mode
201 if ( aPixOffset != aOldPixOffset )
203 Window::SetMapMode( MapMode( MapUnit::MapPixel ) );
204 Window::Scroll(
205 aPixOffset.X() - aOldPixOffset.X(),
206 aPixOffset.Y() - aOldPixOffset.Y() );
207 SetMapMode( aMap );
210 // show or hide scrollbars
211 aVScroll->Show( bVVisible );
212 aHScroll->Show( bHVisible );
214 // disable painting in the corner between the scrollbars
215 if ( bVVisible && bHVisible )
217 aCornerWin->SetPosSizePixel(Point(aOutPixSz.Width(), aOutPixSz.Height()),
218 Size(nScrSize, nScrSize) );
219 aCornerWin->Show();
221 else
222 aCornerWin->Hide();
224 // resize scrollbars and set their ranges
225 if ( bHVisible )
227 aHScroll->SetPosSizePixel(
228 Point( 0, aOutPixSz.Height() ),
229 Size( aOutPixSz.Width(), nScrSize ) );
230 aHScroll->SetRange( Range( 0, aTotPixSz.Width() ) );
231 aHScroll->SetPageSize( aOutPixSz.Width() );
232 aHScroll->SetVisibleSize( aOutPixSz.Width() );
233 aHScroll->SetLineSize( nColumnPixW );
234 aHScroll->SetThumbPos( -aPixOffset.X() );
236 if ( bVVisible )
238 aVScroll->SetPosSizePixel(
239 Point( aOutPixSz.Width(), 0 ),
240 Size( nScrSize,aOutPixSz.Height() ) );
241 aVScroll->SetRange( Range( 0, aTotPixSz.Height() ) );
242 aVScroll->SetPageSize( aOutPixSz.Height() );
243 aVScroll->SetVisibleSize( aOutPixSz.Height() );
244 aVScroll->SetLineSize( nLinePixH );
245 aVScroll->SetThumbPos( -aPixOffset.Y() );
250 void ScrollableWindow::SetMapMode( const MapMode& rNewMapMode )
252 MapMode aMap( rNewMapMode );
253 aMap.SetOrigin( aMap.GetOrigin() + PixelToLogic( aPixOffset, aMap ) );
254 Window::SetMapMode( aMap );
258 MapMode ScrollableWindow::GetMapMode() const
260 MapMode aMap( Window::GetMapMode() );
261 aMap.SetOrigin( aMap.GetOrigin() - PixelToLogic( aPixOffset ) );
262 return aMap;
266 void ScrollableWindow::SetTotalSize( const Size& rNewSize )
268 aTotPixSz = LogicToPixel( rNewSize );
269 ScrollableWindow::Resize();
273 void ScrollableWindow::Scroll( tools::Long nDeltaX, tools::Long nDeltaY, ScrollFlags )
275 // get the delta in pixel
276 Size aDeltaPix( LogicToPixel( Size(nDeltaX, nDeltaY) ) );
277 Size aOutPixSz( GetOutputSizePixel() );
278 MapMode aMap( GetMapMode() );
279 Point aNewPixOffset( aPixOffset );
281 // scrolling horizontally?
282 if ( nDeltaX != 0 )
284 aNewPixOffset.AdjustX( -(aDeltaPix.Width()) );
285 if ( ( aOutPixSz.Width() - aNewPixOffset.X() ) > aTotPixSz.Width() )
286 aNewPixOffset.setX( - ( aTotPixSz.Width() - aOutPixSz.Width() ) );
287 else if ( aNewPixOffset.X() > 0 )
288 aNewPixOffset.setX( 0 );
291 // scrolling vertically?
292 if ( nDeltaY != 0 )
294 aNewPixOffset.AdjustY( -(aDeltaPix.Height()) );
295 if ( ( aOutPixSz.Height() - aNewPixOffset.Y() ) > aTotPixSz.Height() )
296 aNewPixOffset.setY( - ( aTotPixSz.Height() - aOutPixSz.Height() ) );
297 else if ( aNewPixOffset.Y() > 0 )
298 aNewPixOffset.setY( 0 );
301 // recompute the logical scroll units
302 aDeltaPix.setWidth( aPixOffset.X() - aNewPixOffset.X() );
303 aDeltaPix.setHeight( aPixOffset.Y() - aNewPixOffset.Y() );
304 Size aDelta( PixelToLogic(aDeltaPix) );
305 nDeltaX = aDelta.Width();
306 nDeltaY = aDelta.Height();
307 aPixOffset = aNewPixOffset;
309 // scrolling?
310 if ( nDeltaX != 0 || nDeltaY != 0 )
312 PaintImmediately();
314 // does the new area overlap the old one?
315 if ( std::abs( static_cast<int>(aDeltaPix.Height()) ) < aOutPixSz.Height() ||
316 std::abs( static_cast<int>(aDeltaPix.Width()) ) < aOutPixSz.Width() )
318 // scroll the overlapping area
319 SetMapMode( aMap );
321 // never scroll the scrollbars itself!
322 Window::Scroll(-nDeltaX, -nDeltaY,
323 PixelToLogic( tools::Rectangle( Point(0, 0), aOutPixSz ) ) );
325 else
327 // repaint all
328 SetMapMode( aMap );
329 Invalidate();
332 PaintImmediately();
335 if ( !bScrolling )
337 if ( nDeltaX )
338 aHScroll->SetThumbPos( -aPixOffset.X() );
339 if ( nDeltaY )
340 aVScroll->SetThumbPos( -aPixOffset.Y() );
345 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */