Line data Source code
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 :
21 : #include "view/SlsPageObjectLayouter.hxx"
22 :
23 : #include "model/SlsPageDescriptor.hxx"
24 : #include "view/SlsFontProvider.hxx"
25 : #include "view/SlsTheme.hxx"
26 : #include "tools/IconCache.hxx"
27 : #include "Window.hxx"
28 : #include "res_bmp.hrc"
29 :
30 : namespace sd { namespace slidesorter { namespace view {
31 :
32 : namespace {
33 : const static sal_Int32 gnLeftPageNumberOffset = 2;
34 : const static sal_Int32 gnRightPageNumberOffset = 5;
35 : const static sal_Int32 gnOuterBorderWidth = 5;
36 : const static sal_Int32 gnInfoAreaMinWidth = 26;
37 : }
38 :
39 0 : PageObjectLayouter::PageObjectLayouter (
40 : const Size& rPageObjectWindowSize,
41 : const Size& rPageSize,
42 : const SharedSdWindow& rpWindow,
43 : const sal_Int32 nPageCount)
44 : : mpWindow(rpWindow),
45 : maPageObjectSize(rPageObjectWindowSize.Width(), rPageObjectWindowSize.Height()),
46 : maPageObjectBoundingBox(),
47 : maPageNumberAreaBoundingBox(),
48 : maPreviewBoundingBox(),
49 : maTransitionEffectBoundingBox(),
50 0 : maTransitionEffectIcon(IconCache::Instance().GetIcon(BMP_FADE_EFFECT_INDICATOR)),
51 0 : maCustomAnimationEffectIcon(IconCache::Instance().GetIcon(BMP_CUSTOM_ANIMATION_INDICATOR)),
52 0 : mpPageNumberFont(Theme::GetFont(Theme::Font_PageNumber, *rpWindow))
53 : {
54 0 : const Size aPageNumberAreaSize (GetPageNumberAreaSize(nPageCount));
55 :
56 0 : const int nMaximumBorderWidth (gnOuterBorderWidth);
57 0 : const int nFocusIndicatorWidth (Theme_FocusIndicatorWidth);
58 :
59 : maPreviewBoundingBox = CalculatePreviewBoundingBox(
60 : maPageObjectSize,
61 : Size(rPageSize.Width(), rPageSize.Height()),
62 : aPageNumberAreaSize.Width(),
63 0 : nFocusIndicatorWidth);
64 0 : maFocusIndicatorBoundingBox = Rectangle(Point(0,0), maPageObjectSize);
65 : maPageObjectBoundingBox = Rectangle(
66 : Point(
67 : nFocusIndicatorWidth,
68 : nFocusIndicatorWidth),
69 : Size(
70 0 : maPageObjectSize.Width()-2*nFocusIndicatorWidth,
71 0 : maPageObjectSize.Height()-2*nFocusIndicatorWidth));
72 :
73 : maPageNumberAreaBoundingBox = Rectangle(
74 : Point(
75 : std::max(gnLeftPageNumberOffset,
76 0 : sal_Int32(maPreviewBoundingBox.Left()
77 0 : - gnRightPageNumberOffset
78 0 : - aPageNumberAreaSize.Width())),
79 : nMaximumBorderWidth),
80 0 : aPageNumberAreaSize);
81 :
82 0 : const Size aIconSize (maTransitionEffectIcon.GetSizePixel());
83 : maTransitionEffectBoundingBox = Rectangle(
84 : Point(
85 0 : (maPreviewBoundingBox.Left() - 2*aIconSize.Width()) / 2,
86 0 : maPreviewBoundingBox.Bottom() - aIconSize.Height()),
87 0 : aIconSize);
88 : maCustomAnimationEffectBoundingBox = Rectangle(
89 : Point(
90 0 : (maPreviewBoundingBox.Left() - 2*aIconSize.Width()) / 2,
91 0 : maPreviewBoundingBox.Bottom() - 2*aIconSize.Height()),
92 0 : aIconSize);
93 0 : }
94 :
95 :
96 :
97 :
98 0 : PageObjectLayouter::~PageObjectLayouter(void)
99 : {
100 0 : }
101 :
102 :
103 :
104 :
105 0 : Rectangle PageObjectLayouter::CalculatePreviewBoundingBox (
106 : Size& rPageObjectSize,
107 : const Size& rPageSize,
108 : const sal_Int32 nPageNumberAreaWidth,
109 : const sal_Int32 nFocusIndicatorWidth)
110 : {
111 0 : const sal_Int32 nIconWidth (maTransitionEffectIcon.GetSizePixel().Width());
112 : const sal_Int32 nLeftAreaWidth (
113 : ::std::max(
114 : gnInfoAreaMinWidth,
115 : gnRightPageNumberOffset
116 0 : + ::std::max(
117 : nPageNumberAreaWidth,
118 0 : nIconWidth)));
119 : sal_Int32 nPreviewWidth;
120 : sal_Int32 nPreviewHeight;
121 0 : const double nPageAspectRatio (double(rPageSize.Width()) / double(rPageSize.Height()));
122 0 : if (rPageObjectSize.Height() == 0)
123 : {
124 : // Calculate height so that the preview fills the available
125 : // horizontal space completely while observing the aspect ratio of
126 : // the preview.
127 0 : nPreviewWidth = rPageObjectSize.Width()
128 0 : - nLeftAreaWidth - gnOuterBorderWidth - 2*nFocusIndicatorWidth - 1;
129 0 : nPreviewHeight = ::basegfx::fround(nPreviewWidth / nPageAspectRatio);
130 0 : rPageObjectSize.setHeight(nPreviewHeight + 2*gnOuterBorderWidth + 2*nFocusIndicatorWidth + 1);
131 : }
132 0 : else if (rPageObjectSize.Width() == 0)
133 : {
134 : // Calculate the width of the page object so that the preview fills
135 : // the available vertical space completely while observing the
136 : // aspect ratio of the preview.
137 0 : nPreviewHeight = rPageObjectSize.Height() - 2*gnOuterBorderWidth - 2*nFocusIndicatorWidth - 1;
138 0 : nPreviewWidth = ::basegfx::fround(nPreviewHeight * nPageAspectRatio);
139 : rPageObjectSize.setWidth(nPreviewWidth
140 0 : + nLeftAreaWidth + gnOuterBorderWidth + 2*nFocusIndicatorWidth + 1);
141 :
142 : }
143 : else
144 : {
145 : // The size of the page object is given. Calculate the size of the
146 : // preview.
147 0 : nPreviewWidth = rPageObjectSize.Width()
148 0 : - nLeftAreaWidth - gnOuterBorderWidth - 2*nFocusIndicatorWidth - 1;
149 0 : nPreviewHeight = rPageObjectSize.Height()
150 0 : - gnOuterBorderWidth - 2*nFocusIndicatorWidth - 1;
151 0 : if (double(nPreviewWidth)/double(nPreviewHeight) > nPageAspectRatio)
152 0 : nPreviewWidth = ::basegfx::fround(nPreviewHeight * nPageAspectRatio);
153 : else
154 0 : nPreviewHeight = ::basegfx::fround(nPreviewWidth / nPageAspectRatio);
155 : }
156 : // When the preview does not fill the available space completely then
157 : // place it flush right and vertically centered.
158 0 : const int nLeft (rPageObjectSize.Width()
159 0 : - gnOuterBorderWidth - nPreviewWidth - nFocusIndicatorWidth - 1);
160 0 : const int nTop ((rPageObjectSize.Height() - nPreviewHeight)/2);
161 : return Rectangle(
162 : nLeft,
163 : nTop,
164 : nLeft + nPreviewWidth,
165 0 : nTop + nPreviewHeight);
166 : }
167 :
168 :
169 :
170 :
171 0 : Rectangle PageObjectLayouter::GetBoundingBox (
172 : const model::SharedPageDescriptor& rpPageDescriptor,
173 : const Part ePart,
174 : const CoordinateSystem eCoordinateSystem)
175 : {
176 : OSL_ASSERT(rpPageDescriptor);
177 0 : Point aLocation (rpPageDescriptor ? rpPageDescriptor->GetLocation() : Point(0,0));
178 0 : return GetBoundingBox(aLocation, ePart, eCoordinateSystem);
179 : }
180 :
181 :
182 :
183 :
184 0 : Rectangle PageObjectLayouter::GetBoundingBox (
185 : const Point& rPageObjectLocation,
186 : const Part ePart,
187 : const CoordinateSystem eCoordinateSystem)
188 : {
189 0 : Rectangle aBoundingBox;
190 0 : switch (ePart)
191 : {
192 : case FocusIndicator:
193 0 : aBoundingBox = maFocusIndicatorBoundingBox;
194 0 : break;
195 :
196 : case PageObject:
197 : case MouseOverIndicator:
198 0 : aBoundingBox = maPageObjectBoundingBox;
199 0 : break;
200 :
201 : case Preview:
202 0 : aBoundingBox = maPreviewBoundingBox;
203 0 : break;
204 :
205 : case PageNumber:
206 0 : aBoundingBox = maPageNumberAreaBoundingBox;
207 0 : break;
208 :
209 : case Name:
210 0 : aBoundingBox = maPageNumberAreaBoundingBox;
211 0 : break;
212 :
213 : case TransitionEffectIndicator:
214 0 : aBoundingBox = maTransitionEffectBoundingBox;
215 0 : break;
216 : case CustomAnimationEffectIndicator:
217 0 : aBoundingBox = maCustomAnimationEffectBoundingBox;
218 0 : break;
219 : }
220 :
221 : // Adapt coordinates to the requested coordinate system.
222 0 : Point aLocation (rPageObjectLocation);
223 0 : if (eCoordinateSystem == WindowCoordinateSystem)
224 0 : aLocation += mpWindow->GetMapMode().GetOrigin();
225 :
226 : return Rectangle(
227 0 : aBoundingBox.TopLeft() + aLocation,
228 0 : aBoundingBox.BottomRight() + aLocation);
229 : }
230 :
231 :
232 :
233 :
234 0 : Size PageObjectLayouter::GetSize (
235 : const Part ePart,
236 : const CoordinateSystem eCoordinateSystem)
237 : {
238 0 : return GetBoundingBox(Point(0,0), ePart, eCoordinateSystem).GetSize();
239 : }
240 :
241 :
242 :
243 :
244 0 : Size PageObjectLayouter::GetPageNumberAreaSize (const int nPageCount)
245 : {
246 : OSL_ASSERT(mpWindow);
247 :
248 : // Set the correct font.
249 0 : Font aOriginalFont (mpWindow->GetFont());
250 0 : if (mpPageNumberFont)
251 0 : mpWindow->SetFont(*mpPageNumberFont);
252 :
253 0 : OUString sPageNumberTemplate;
254 0 : if (nPageCount < 10)
255 0 : sPageNumberTemplate = "9";
256 0 : else if (nPageCount < 100)
257 0 : sPageNumberTemplate = "99";
258 0 : else if (nPageCount < 200)
259 : // Just for the case that 1 is narrower than 9.
260 0 : sPageNumberTemplate = "199";
261 0 : else if (nPageCount < 1000)
262 0 : sPageNumberTemplate = "999";
263 : else
264 0 : sPageNumberTemplate = "9999";
265 : // More then 9999 pages are not handled.
266 :
267 : const Size aSize (
268 0 : mpWindow->GetTextWidth(sPageNumberTemplate),
269 0 : mpWindow->GetTextHeight());
270 :
271 0 : mpWindow->SetFont(aOriginalFont);
272 :
273 0 : return aSize;
274 : }
275 :
276 :
277 :
278 :
279 0 : Image PageObjectLayouter::GetTransitionEffectIcon (void) const
280 : {
281 0 : return maTransitionEffectIcon;
282 : }
283 :
284 0 : Image PageObjectLayouter::GetCustomAnimationEffectIcon (void) const
285 : {
286 0 : return maCustomAnimationEffectIcon;
287 : }
288 :
289 :
290 : } } } // end of namespace ::sd::slidesorter::view
291 :
292 : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
|