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