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