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 <view/SlsPageObjectLayouter.hxx>
22 #include <model/SlsPageDescriptor.hxx>
23 #include <view/SlsTheme.hxx>
24 #include <tools/IconCache.hxx>
27 #include <bitmaps.hlst>
28 #include <osl/diagnose.h>
30 namespace sd::slidesorter::view
{
33 const sal_Int32 gnLeftPageNumberOffset
= 2;
34 const sal_Int32 gnRightPageNumberOffset
= 5;
35 const sal_Int32 gnOuterBorderWidth
= 5;
36 const sal_Int32 gnInfoAreaMinWidth
= 26;
39 PageObjectLayouter::PageObjectLayouter (
40 const Size
& rPageObjectWindowSize
,
41 const Size
& rPageSize
,
43 const sal_Int32 nPageCount
)
45 maTransitionEffectIcon(IconCache::Instance().GetIcon(BMP_FADE_EFFECT_INDICATOR
)),
46 maCustomAnimationEffectIcon(IconCache::Instance().GetIcon(BMP_CUSTOM_ANIMATION_INDICATOR
)),
47 mpPageNumberFont(Theme::GetFont(Theme::Font_PageNumber
, *pWindow
->GetOutDev()))
49 const Size
aPageNumberAreaSize (GetPageNumberAreaSize(nPageCount
));
51 const int nMaximumBorderWidth (gnOuterBorderWidth
);
52 const int nFocusIndicatorWidth (Theme_FocusIndicatorWidth
);
54 Size
aPageObjectSize(rPageObjectWindowSize
.Width(), rPageObjectWindowSize
.Height());
55 maPreviewBoundingBox
= CalculatePreviewBoundingBox(
57 Size(rPageSize
.Width(), rPageSize
.Height()),
58 aPageNumberAreaSize
.Width(),
59 nFocusIndicatorWidth
);
60 maFocusIndicatorBoundingBox
= ::tools::Rectangle(Point(0,0), aPageObjectSize
);
61 maPageObjectBoundingBox
= ::tools::Rectangle(
64 nFocusIndicatorWidth
),
66 aPageObjectSize
.Width()-2*nFocusIndicatorWidth
,
67 aPageObjectSize
.Height()-2*nFocusIndicatorWidth
));
69 maPageNumberAreaBoundingBox
= ::tools::Rectangle(
71 std::max(gnLeftPageNumberOffset
,
72 sal_Int32(maPreviewBoundingBox
.Left()
73 - gnRightPageNumberOffset
74 - aPageNumberAreaSize
.Width())),
78 const Size
aIconSize (maTransitionEffectIcon
.GetSizePixel());
79 maTransitionEffectBoundingBox
= ::tools::Rectangle(
81 (maPreviewBoundingBox
.Left() - 2*aIconSize
.Width()) / 2,
82 maPreviewBoundingBox
.Bottom() - aIconSize
.Height()),
84 maCustomAnimationEffectBoundingBox
= ::tools::Rectangle(
86 (maPreviewBoundingBox
.Left() - 2*aIconSize
.Width()) / 2,
87 maPreviewBoundingBox
.Bottom() - 2*aIconSize
.Height()),
91 PageObjectLayouter::~PageObjectLayouter()
95 ::tools::Rectangle
PageObjectLayouter::CalculatePreviewBoundingBox (
96 Size
& rPageObjectSize
,
97 const Size
& rPageSize
,
98 const sal_Int32 nPageNumberAreaWidth
,
99 const sal_Int32 nFocusIndicatorWidth
)
101 const sal_Int32
nIconWidth (maTransitionEffectIcon
.GetSizePixel().Width());
102 const sal_Int32
nLeftAreaWidth (
105 gnRightPageNumberOffset
107 nPageNumberAreaWidth
,
109 sal_Int32 nPreviewWidth
;
110 sal_Int32 nPreviewHeight
;
111 const double nPageAspectRatio (double(rPageSize
.Width()) / double(rPageSize
.Height()));
112 if (rPageObjectSize
.Height() == 0)
114 // Calculate height so that the preview fills the available
115 // horizontal space completely while observing the aspect ratio of
117 nPreviewWidth
= rPageObjectSize
.Width()
118 - nLeftAreaWidth
- gnOuterBorderWidth
- 2*nFocusIndicatorWidth
- 1;
119 nPreviewHeight
= ::basegfx::fround(nPreviewWidth
/ nPageAspectRatio
);
120 rPageObjectSize
.setHeight(nPreviewHeight
+ 2*gnOuterBorderWidth
+ 2*nFocusIndicatorWidth
+ 1);
122 else if (rPageObjectSize
.Width() == 0)
124 // Calculate the width of the page object so that the preview fills
125 // the available vertical space completely while observing the
126 // aspect ratio of the preview.
127 nPreviewHeight
= rPageObjectSize
.Height() - 2*gnOuterBorderWidth
- 2*nFocusIndicatorWidth
- 1;
128 nPreviewWidth
= ::basegfx::fround(nPreviewHeight
* nPageAspectRatio
);
129 rPageObjectSize
.setWidth(nPreviewWidth
130 + nLeftAreaWidth
+ gnOuterBorderWidth
+ 2*nFocusIndicatorWidth
+ 1);
135 // The size of the page object is given. Calculate the size of the
137 nPreviewWidth
= rPageObjectSize
.Width()
138 - nLeftAreaWidth
- gnOuterBorderWidth
- 2*nFocusIndicatorWidth
- 1;
139 nPreviewHeight
= rPageObjectSize
.Height()
140 - gnOuterBorderWidth
- 2*nFocusIndicatorWidth
- 1;
141 if (double(nPreviewWidth
)/double(nPreviewHeight
) > nPageAspectRatio
)
142 nPreviewWidth
= ::basegfx::fround(nPreviewHeight
* nPageAspectRatio
);
144 nPreviewHeight
= ::basegfx::fround(nPreviewWidth
/ nPageAspectRatio
);
146 // When the preview does not fill the available space completely then
147 // place it flush right and vertically centered.
148 const int nLeft (rPageObjectSize
.Width()
149 - gnOuterBorderWidth
- nPreviewWidth
- nFocusIndicatorWidth
- 1);
150 const int nTop ((rPageObjectSize
.Height() - nPreviewHeight
)/2);
151 return ::tools::Rectangle(
154 nLeft
+ nPreviewWidth
,
155 nTop
+ nPreviewHeight
);
158 ::tools::Rectangle
PageObjectLayouter::GetBoundingBox (
159 const model::SharedPageDescriptor
& rpPageDescriptor
,
161 const CoordinateSystem eCoordinateSystem
,
162 bool bIgnoreLocation
)
164 OSL_ASSERT(rpPageDescriptor
);
165 Point
aLocation(0,0);
166 if (rpPageDescriptor
)
167 aLocation
= rpPageDescriptor
->GetLocation( bIgnoreLocation
);
168 return GetBoundingBox(aLocation
, ePart
, eCoordinateSystem
);
171 ::tools::Rectangle
PageObjectLayouter::GetBoundingBox (
172 const Point
& rPageObjectLocation
,
174 const CoordinateSystem eCoordinateSystem
)
176 ::tools::Rectangle aBoundingBox
;
179 case Part::FocusIndicator
:
180 aBoundingBox
= maFocusIndicatorBoundingBox
;
183 case Part::PageObject
:
184 aBoundingBox
= maPageObjectBoundingBox
;
188 aBoundingBox
= maPreviewBoundingBox
;
191 case Part::PageNumber
:
192 aBoundingBox
= maPageNumberAreaBoundingBox
;
195 case Part::TransitionEffectIndicator
:
196 aBoundingBox
= maTransitionEffectBoundingBox
;
198 case Part::CustomAnimationEffectIndicator
:
199 aBoundingBox
= maCustomAnimationEffectBoundingBox
;
203 // Adapt coordinates to the requested coordinate system.
204 Point
aLocation (rPageObjectLocation
);
205 if (eCoordinateSystem
== WindowCoordinateSystem
)
206 aLocation
+= mpWindow
->GetMapMode().GetOrigin();
208 return ::tools::Rectangle(
209 aBoundingBox
.TopLeft() + aLocation
,
210 aBoundingBox
.BottomRight() + aLocation
);
213 Size
PageObjectLayouter::GetPreviewSize ()
215 return GetBoundingBox(Point(0,0), PageObjectLayouter::Part::Preview
,
216 WindowCoordinateSystem
).GetSize();
219 Size
PageObjectLayouter::GetGridMaxSize()
221 return GetBoundingBox(Point(0,0), PageObjectLayouter::Part::FocusIndicator
,
222 WindowCoordinateSystem
).GetSize();
225 Size
PageObjectLayouter::GetPageNumberAreaSize (const int nPageCount
)
227 OSL_ASSERT(mpWindow
);
229 // Set the correct font.
230 vcl::Font
aOriginalFont (mpWindow
->GetFont());
231 if (mpPageNumberFont
)
232 mpWindow
->SetFont(*mpPageNumberFont
);
234 OUString sPageNumberTemplate
;
236 sPageNumberTemplate
= "9";
237 else if (nPageCount
< 100)
238 sPageNumberTemplate
= "99";
239 else if (nPageCount
< 200)
240 // Just for the case that 1 is narrower than 9.
241 sPageNumberTemplate
= "199";
242 else if (nPageCount
< 1000)
243 sPageNumberTemplate
= "999";
245 sPageNumberTemplate
= "9999";
246 // More than 9999 pages are not handled.
249 mpWindow
->GetTextWidth(sPageNumberTemplate
),
250 mpWindow
->GetTextHeight());
252 mpWindow
->SetFont(aOriginalFont
);
257 } // end of namespace ::sd::slidesorter::view
259 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */