LibreOffice Module sd (master) 1
SlsVisibleAreaManager.cxx
Go to the documentation of this file.
1/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2/*
3 * This file is part of the LibreOffice project.
4 *
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/.
8 *
9 * This file incorporates work covered by the following license notice:
10 *
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 .
18 */
19
20#include <sal/config.h>
21
27#include <Window.hxx>
28#include <SlideSorter.hxx>
30
32
33namespace {
34 class VisibleAreaScroller
35 {
36 public:
37 VisibleAreaScroller (
38 SlideSorter& rSlideSorter,
39 const Point& rStart,
40 const Point& rEnd);
41 void operator() (const double nValue);
42 private:
45 const Point maEnd;
46 const ::std::function<double (double)> maAccelerationFunction;
47 };
48
49} // end of anonymous namespace
50
52 : mrSlideSorter(rSlideSorter),
54 mnDisableCount(0)
55{
56}
57
59{
60}
61
63{
65}
66
68{
70}
71
73 const model::SharedPageDescriptor& rpDescriptor,
74 const bool bForce)
75{
76 if (!rpDescriptor)
77 return;
78
79 if (mnDisableCount == 0)
80 {
81 maVisibleRequests.push_back(
83 rpDescriptor->GetPageIndex(),
84 true));
85 }
86 if (bForce && ! mbIsCurrentSlideTrackingActive)
89}
90
92{
96}
97
99{
100 if (maVisibleRequests.empty())
101 return;
102
104 if ( ! pWindow)
105 return;
106 const Point aCurrentTopLeft (pWindow->PixelToLogic(Point(0,0)));
107
108 const ::std::optional<Point> aNewVisibleTopLeft (GetRequestedTopLeft());
109 maVisibleRequests.clear();
110 if ( ! aNewVisibleTopLeft)
111 return;
112
113 maRequestedVisibleTopLeft = *aNewVisibleTopLeft;
114 VisibleAreaScroller aAnimation(
116 aCurrentTopLeft,
118 // Execute the animation at its final value.
119 aAnimation(1.0);
120}
121
122::std::optional<Point> VisibleAreaManager::GetRequestedTopLeft() const
123{
125 if ( ! pWindow)
126 return ::std::optional<Point>();
127
128 // Get the currently visible area and the model area.
129 const ::tools::Rectangle aVisibleArea (pWindow->PixelToLogic(
131 Point(0,0),
132 pWindow->GetOutputSizePixel())));
133 const ::tools::Rectangle aModelArea (mrSlideSorter.GetView().GetModelArea());
134
135 sal_Int32 nVisibleTop (aVisibleArea.Top());
136 const sal_Int32 nVisibleWidth (aVisibleArea.GetWidth());
137 sal_Int32 nVisibleLeft (aVisibleArea.Left());
138 const sal_Int32 nVisibleHeight (aVisibleArea.GetHeight());
139
140 // Find the longest run of boxes whose union fits into the visible area.
141 for (const auto& rBox : maVisibleRequests)
142 {
143 if (nVisibleTop+nVisibleHeight <= rBox.Bottom())
144 nVisibleTop = rBox.Bottom()-nVisibleHeight;
145 if (nVisibleTop > rBox.Top())
146 nVisibleTop = rBox.Top();
147
148 if (nVisibleLeft+nVisibleWidth <= rBox.Right())
149 nVisibleLeft = rBox.Right()-nVisibleWidth;
150 if (nVisibleLeft > rBox.Left())
151 nVisibleLeft = rBox.Left();
152
153 // Make sure the visible area does not move outside the model area.
154 if (nVisibleTop + nVisibleHeight > aModelArea.Bottom())
155 nVisibleTop = aModelArea.Bottom() - nVisibleHeight;
156 if (nVisibleTop < aModelArea.Top())
157 nVisibleTop = aModelArea.Top();
158
159 if (nVisibleLeft + nVisibleWidth > aModelArea.Right())
160 nVisibleLeft = aModelArea.Right() - nVisibleWidth;
161 if (nVisibleLeft < aModelArea.Left())
162 nVisibleLeft = aModelArea.Left();
163 }
164
165 const Point aRequestedTopLeft (nVisibleLeft, nVisibleTop);
166 if (aRequestedTopLeft == aVisibleArea.TopLeft())
167 return ::std::optional<Point>();
168 else
169 return ::std::optional<Point>(aRequestedTopLeft);
170}
171
172//===== VisibleAreaManager::TemporaryDisabler =================================
173
175 : mrVisibleAreaManager(rSlideSorter.GetController().GetVisibleAreaManager())
176{
178}
179
181{
182 --mrVisibleAreaManager.mnDisableCount;
183}
184
185//===== VerticalVisibleAreaScroller ===========================================
186
187namespace {
188
189const sal_Int32 gnMaxScrollDistance = 300;
190
191VisibleAreaScroller::VisibleAreaScroller (
192 SlideSorter& rSlideSorter,
193 const Point& rStart,
194 const Point& rEnd)
195 : mrSlideSorter(rSlideSorter),
196 maStart(rStart),
197 maEnd(rEnd),
199 controller::AnimationParametricFunction(
200 controller::AnimationBezierFunction (0.1,0.6)))
201{
202 // When the distance to scroll is larger than a threshold then first
203 // jump to within this distance of the final value and start the
204 // animation from there.
205 if (std::abs(rStart.X()-rEnd.X()) > gnMaxScrollDistance)
206 {
207 if (rStart.X() < rEnd.X())
208 maStart.setX( rEnd.X()-gnMaxScrollDistance );
209 else
210 maStart.setX( rEnd.X()+gnMaxScrollDistance );
211 }
212 if (std::abs(rStart.Y()-rEnd.Y()) > gnMaxScrollDistance)
213 {
214 if (rStart.Y() < rEnd.Y())
215 maStart.setY( rEnd.Y()-gnMaxScrollDistance );
216 else
217 maStart.setY( rEnd.Y()+gnMaxScrollDistance );
218 }
219}
220
221void VisibleAreaScroller::operator() (const double nTime)
222{
223 const double nLocalTime (maAccelerationFunction(nTime));
225 Point(
226 sal_Int32(0.5 + maStart.X() * (1.0 - nLocalTime) + maEnd.X() * nLocalTime),
227 sal_Int32 (0.5 + maStart.Y() * (1.0 - nLocalTime) + maEnd.Y() * nLocalTime)));
228}
229
230} // end of anonymous namespace
231
232} // end of namespace ::sd::slidesorter::controller
233
234/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
const bool mbIsCurrentSlideTrackingActive
Point maStart
const ::std::function< double(double)> maAccelerationFunction
const Point maEnd
SlideSorter & mrSlideSorter
constexpr tools::Long Y() const
void setX(tools::Long nX)
void setY(tools::Long nY)
constexpr tools::Long X() const
reference_type * get() const
An SdWindow contains the actual working area of ViewShell.
Definition: Window.hxx:45
Show previews for all the slides in a document and allow the user to insert or delete slides and modi...
Definition: SlideSorter.hxx:62
SD_DLLPUBLIC controller::SlideSorterController & GetController() const
const VclPtr< sd::Window > & GetContentWindow() const
Return the content window.
Definition: SlideSorter.hxx:99
view::SlideSorterView & GetView() const
Turn a parametric function into one whose y-Values depend on its x-Values.
void SetTopLeft(const Point &rNewTopLeft)
Update the vertical and horizontal scroll bars so that the visible area has the given top and left va...
std::shared_ptr< CurrentSlideManager > const & GetCurrentSlideManager() const
ScrollBarManager & GetScrollBarManager()
Return the object that manages the scroll bars.
void RequestCurrentSlideVisible()
Request the current slide to be moved into the visible area.
::std::vector<::tools::Rectangle > maVisibleRequests
List of rectangle that someone wants to be moved into the visible area.
void RequestVisible(const model::SharedPageDescriptor &rpDescriptor, const bool bForce=false)
Request to make the specified page object visible.
::tools::Rectangle GetPageObjectBox(const sal_Int32 nIndex, const bool bIncludeBorderAndGap) const
Return the bounding box in window coordinates of the nIndex-th page object.
::tools::Rectangle GetModelArea() const
Point PixelToLogic(const Point &rDevicePt) const
Size GetOutputSizePixel() const
virtual std::shared_ptr< SfxDialogController > GetController() override
std::shared_ptr< PageDescriptor > SharedPageDescriptor