1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
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 <sal/config.h>
24 #include <controller/SlsVisibleAreaManager.hxx>
25 #include <controller/SlideSorterController.hxx>
26 #include <controller/SlsProperties.hxx>
27 #include <controller/SlsAnimationFunction.hxx>
28 #include <controller/SlsScrollBarManager.hxx>
29 #include <controller/SlsCurrentSlideManager.hxx>
31 #include <SlideSorter.hxx>
32 #include <view/SlideSorterView.hxx>
34 namespace sd
{ namespace slidesorter
{ namespace controller
{
37 class VisibleAreaScroller
41 SlideSorter
& rSlideSorter
,
44 void operator() (const double nValue
);
46 SlideSorter
& mrSlideSorter
;
49 const ::std::function
<double (double)> maAccelerationFunction
;
52 } // end of anonymous namespace
54 VisibleAreaManager::VisibleAreaManager (SlideSorter
& rSlideSorter
)
55 : mrSlideSorter(rSlideSorter
),
57 maRequestedVisibleTopLeft(),
58 mbIsCurrentSlideTrackingActive(true),
63 VisibleAreaManager::~VisibleAreaManager()
67 void VisibleAreaManager::ActivateCurrentSlideTracking()
69 mbIsCurrentSlideTrackingActive
= true;
72 void VisibleAreaManager::DeactivateCurrentSlideTracking()
74 mbIsCurrentSlideTrackingActive
= false;
77 void VisibleAreaManager::RequestVisible (
78 const model::SharedPageDescriptor
& rpDescriptor
,
84 if (mnDisableCount
== 0)
86 maVisibleRequests
.push_back(
87 mrSlideSorter
.GetView().GetLayouter().GetPageObjectBox(
88 rpDescriptor
->GetPageIndex(),
91 if (bForce
&& ! mbIsCurrentSlideTrackingActive
)
92 ActivateCurrentSlideTracking();
96 void VisibleAreaManager::RequestCurrentSlideVisible()
98 if (mbIsCurrentSlideTrackingActive
&& mnDisableCount
==0)
100 mrSlideSorter
.GetController().GetCurrentSlideManager()->GetCurrentSlide());
103 void VisibleAreaManager::MakeVisible()
105 if (maVisibleRequests
.empty())
108 sd::Window
*pWindow (mrSlideSorter
.GetContentWindow().get());
111 const Point
aCurrentTopLeft (pWindow
->PixelToLogic(Point(0,0)));
113 const ::boost::optional
<Point
> aNewVisibleTopLeft (GetRequestedTopLeft());
114 maVisibleRequests
.clear();
115 if ( ! aNewVisibleTopLeft
)
118 maRequestedVisibleTopLeft
= aNewVisibleTopLeft
.get();
119 VisibleAreaScroller
aAnimation(
122 maRequestedVisibleTopLeft
);
123 // Execute the animation at its final value.
127 ::boost::optional
<Point
> VisibleAreaManager::GetRequestedTopLeft() const
129 sd::Window
*pWindow (mrSlideSorter
.GetContentWindow().get());
131 return ::boost::optional
<Point
>();
133 // Get the currently visible area and the model area.
134 const ::tools::Rectangle
aVisibleArea (pWindow
->PixelToLogic(
137 pWindow
->GetOutputSizePixel())));
138 const ::tools::Rectangle
aModelArea (mrSlideSorter
.GetView().GetModelArea());
140 sal_Int32
nVisibleTop (aVisibleArea
.Top());
141 const sal_Int32
nVisibleWidth (aVisibleArea
.GetWidth());
142 sal_Int32
nVisibleLeft (aVisibleArea
.Left());
143 const sal_Int32
nVisibleHeight (aVisibleArea
.GetHeight());
145 // Find the longest run of boxes whose union fits into the visible area.
146 for (const auto& rBox
: maVisibleRequests
)
148 if (nVisibleTop
+nVisibleHeight
<= rBox
.Bottom())
149 nVisibleTop
= rBox
.Bottom()-nVisibleHeight
;
150 if (nVisibleTop
> rBox
.Top())
151 nVisibleTop
= rBox
.Top();
153 if (nVisibleLeft
+nVisibleWidth
<= rBox
.Right())
154 nVisibleLeft
= rBox
.Right()-nVisibleWidth
;
155 if (nVisibleLeft
> rBox
.Left())
156 nVisibleLeft
= rBox
.Left();
158 // Make sure the visible area does not move outside the model area.
159 if (nVisibleTop
+ nVisibleHeight
> aModelArea
.Bottom())
160 nVisibleTop
= aModelArea
.Bottom() - nVisibleHeight
;
161 if (nVisibleTop
< aModelArea
.Top())
162 nVisibleTop
= aModelArea
.Top();
164 if (nVisibleLeft
+ nVisibleWidth
> aModelArea
.Right())
165 nVisibleLeft
= aModelArea
.Right() - nVisibleWidth
;
166 if (nVisibleLeft
< aModelArea
.Left())
167 nVisibleLeft
= aModelArea
.Left();
170 const Point
aRequestedTopLeft (nVisibleLeft
, nVisibleTop
);
171 if (aRequestedTopLeft
== aVisibleArea
.TopLeft())
172 return ::boost::optional
<Point
>();
174 return ::boost::optional
<Point
>(aRequestedTopLeft
);
177 //===== VisibleAreaManager::TemporaryDisabler =================================
179 VisibleAreaManager::TemporaryDisabler::TemporaryDisabler (SlideSorter
const & rSlideSorter
)
180 : mrVisibleAreaManager(rSlideSorter
.GetController().GetVisibleAreaManager())
182 ++mrVisibleAreaManager
.mnDisableCount
;
185 VisibleAreaManager::TemporaryDisabler::~TemporaryDisabler()
187 --mrVisibleAreaManager
.mnDisableCount
;
190 //===== VerticalVisibleAreaScroller ===========================================
194 const static sal_Int32 gnMaxScrollDistance
= 300;
196 VisibleAreaScroller::VisibleAreaScroller (
197 SlideSorter
& rSlideSorter
,
200 : mrSlideSorter(rSlideSorter
),
203 maAccelerationFunction(
204 controller::AnimationParametricFunction(
205 controller::AnimationBezierFunction (0.1,0.6)))
207 // When the distance to scroll is larger than a threshold then first
208 // jump to within this distance of the final value and start the
209 // animation from there.
210 if (std::abs(rStart
.X()-rEnd
.X()) > gnMaxScrollDistance
)
212 if (rStart
.X() < rEnd
.X())
213 maStart
.setX( rEnd
.X()-gnMaxScrollDistance
);
215 maStart
.setX( rEnd
.X()+gnMaxScrollDistance
);
217 if (std::abs(rStart
.Y()-rEnd
.Y()) > gnMaxScrollDistance
)
219 if (rStart
.Y() < rEnd
.Y())
220 maStart
.setY( rEnd
.Y()-gnMaxScrollDistance
);
222 maStart
.setY( rEnd
.Y()+gnMaxScrollDistance
);
226 void VisibleAreaScroller::operator() (const double nTime
)
228 const double nLocalTime (maAccelerationFunction(nTime
));
229 mrSlideSorter
.GetController().GetScrollBarManager().SetTopLeft(
231 sal_Int32(0.5 + maStart
.X() * (1.0 - nLocalTime
) + maEnd
.X() * nLocalTime
),
232 sal_Int32 (0.5 + maStart
.Y() * (1.0 - nLocalTime
) + maEnd
.Y() * nLocalTime
)));
235 } // end of anonymous namespace
237 } } } // end of namespace ::sd::slidesorter::controller
239 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */