1 /**************************************************************
2 *
3 * Licensed to the Apache Software Foundation (ASF) under one
4 * or more contributor license agreements. See the NOTICE file
5 * distributed with this work for additional information
6 * regarding copyright ownership. The ASF licenses this file
7 * to you under the Apache License, Version 2.0 (the
8 * "License"); you may not use this file except in compliance
9 * with the License. You may obtain a copy of the License at
10 *
11 * http://www.apache.org/licenses/LICENSE-2.0
12 *
13 * Unless required by applicable law or agreed to in writing,
14 * software distributed under the License is distributed on an
15 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
16 * KIND, either express or implied. See the License for the
17 * specific language governing permissions and limitations
18 * under the License.
19 *
20 *************************************************************/
21
22
23
24 #include "precompiled_sd.hxx"
25
26 #include "view/SlsPageObjectLayouter.hxx"
27
28 #include "model/SlsPageDescriptor.hxx"
29 #include "view/SlsFontProvider.hxx"
30 #include "view/SlsTheme.hxx"
31 #include "tools/IconCache.hxx"
32 #include "Window.hxx"
33 #include "res_bmp.hrc"
34
35 namespace sd { namespace slidesorter { namespace view {
36
37 namespace {
38 const static sal_Int32 gnLeftPageNumberOffset = 2;
39 const static sal_Int32 gnRightPageNumberOffset = 5;
40 const static sal_Int32 gnOuterBorderWidth = 5;
41 const static sal_Int32 gnInfoAreaMinWidth = 26;
42 }
43
PageObjectLayouter(const::boost::shared_ptr<Theme> & rpTheme,const Size & rPageObjectWindowSize,const Size & rPageSize,const SharedSdWindow & rpWindow,const sal_Int32 nPageCount)44 PageObjectLayouter::PageObjectLayouter (
45 const ::boost::shared_ptr<Theme>& rpTheme,
46 const Size& rPageObjectWindowSize,
47 const Size& rPageSize,
48 const SharedSdWindow& rpWindow,
49 const sal_Int32 nPageCount)
50 : mpWindow(rpWindow),
51 maPageObjectSize(rPageObjectWindowSize.Width(), rPageObjectWindowSize.Height()),
52 mnModelToWindowScale(1),
53 maPageObjectBoundingBox(),
54 maPageNumberAreaBoundingBox(),
55 maPreviewBoundingBox(),
56 maTransitionEffectBoundingBox(),
57 maTransitionEffectIcon(IconCache::Instance().GetIcon(BMP_FADE_EFFECT_INDICATOR)),
58 mpPageNumberFont(Theme::GetFont(Theme::Font_PageNumber, *rpWindow))
59 {
60 const Size aPageNumberAreaSize (GetPageNumberAreaSize(nPageCount));
61
62 const int nMaximumBorderWidth (gnOuterBorderWidth);
63 const int nFocusIndicatorWidth (rpTheme->GetIntegerValue(Theme::Integer_FocusIndicatorWidth));
64
65 maPreviewBoundingBox = CalculatePreviewBoundingBox(
66 maPageObjectSize,
67 Size(rPageSize.Width(), rPageSize.Height()),
68 aPageNumberAreaSize.Width(),
69 nFocusIndicatorWidth);
70 maFocusIndicatorBoundingBox = Rectangle(Point(0,0), maPageObjectSize);
71 maPageObjectBoundingBox = Rectangle(
72 Point(
73 nFocusIndicatorWidth,
74 nFocusIndicatorWidth),
75 Size(
76 maPageObjectSize.Width()-2*nFocusIndicatorWidth,
77 maPageObjectSize.Height()-2*nFocusIndicatorWidth));
78
79 maPageNumberAreaBoundingBox = Rectangle(
80 Point(
81 std::max(gnLeftPageNumberOffset,
82 sal_Int32(maPreviewBoundingBox.Left()
83 - gnRightPageNumberOffset
84 - aPageNumberAreaSize.Width())),
85 nMaximumBorderWidth),
86 aPageNumberAreaSize);
87
88 const Size aIconSize (maTransitionEffectIcon.GetSizePixel());
89 maTransitionEffectBoundingBox = Rectangle(
90 Point(
91 (maPreviewBoundingBox.Left() - aIconSize.Width()) / 2,
92 maPreviewBoundingBox.Bottom() - aIconSize.Height()),
93 aIconSize);
94 }
95
96
97
98
~PageObjectLayouter(void)99 PageObjectLayouter::~PageObjectLayouter(void)
100 {
101 }
102
103
104
105
CalculatePreviewBoundingBox(Size & rPageObjectSize,const Size & rPageSize,const sal_Int32 nPageNumberAreaWidth,const sal_Int32 nFocusIndicatorWidth)106 Rectangle PageObjectLayouter::CalculatePreviewBoundingBox (
107 Size& rPageObjectSize,
108 const Size& rPageSize,
109 const sal_Int32 nPageNumberAreaWidth,
110 const sal_Int32 nFocusIndicatorWidth)
111 {
112 const sal_Int32 nIconWidth (maTransitionEffectIcon.GetSizePixel().Width());
113 const sal_Int32 nLeftAreaWidth (
114 ::std::max(
115 gnInfoAreaMinWidth,
116 gnRightPageNumberOffset
117 + ::std::max(
118 nPageNumberAreaWidth,
119 nIconWidth)));
120 sal_Int32 nPreviewWidth;
121 sal_Int32 nPreviewHeight;
122 const double nPageAspectRatio (double(rPageSize.Width()) / double(rPageSize.Height()));
123 if (rPageObjectSize.Height() == 0)
124 {
125 // Calculate height so that the preview fills the available
126 // horizontal space completely while observing the aspect ratio of
127 // the preview.
128 nPreviewWidth = rPageObjectSize.Width()
129 - nLeftAreaWidth - gnOuterBorderWidth - 2*nFocusIndicatorWidth - 1;
130 nPreviewHeight = ::basegfx::fround(nPreviewWidth / nPageAspectRatio);
131 rPageObjectSize.setHeight(nPreviewHeight + 2*gnOuterBorderWidth + 2*nFocusIndicatorWidth + 1);
132 }
133 else if (rPageObjectSize.Width() == 0)
134 {
135 // Calculate the width of the page object so that the preview fills
136 // the available vertical space completely while observing the
137 // aspect ratio of the preview.
138 nPreviewHeight = rPageObjectSize.Height() - 2*gnOuterBorderWidth - 2*nFocusIndicatorWidth - 1;
139 nPreviewWidth = ::basegfx::fround(nPreviewHeight * nPageAspectRatio);
140 rPageObjectSize.setWidth(nPreviewWidth
141 + nLeftAreaWidth + gnOuterBorderWidth + 2*nFocusIndicatorWidth + 1);
142
143 }
144 else
145 {
146 // The size of the page object is given. Calculate the size of the
147 // preview.
148 nPreviewWidth = rPageObjectSize.Width()
149 - nLeftAreaWidth - gnOuterBorderWidth - 2*nFocusIndicatorWidth - 1;
150 nPreviewHeight = rPageObjectSize.Height()
151 - gnOuterBorderWidth - 2*nFocusIndicatorWidth - 1;
152 if (double(nPreviewWidth)/double(nPreviewHeight) > nPageAspectRatio)
153 nPreviewWidth = ::basegfx::fround(nPreviewHeight * nPageAspectRatio);
154 else
155 nPreviewHeight = ::basegfx::fround(nPreviewWidth / nPageAspectRatio);
156 }
157 // When the preview does not fill the available space completely then
158 // place it flush right and vertically centered.
159 const int nLeft (rPageObjectSize.Width()
160 - gnOuterBorderWidth - nPreviewWidth - nFocusIndicatorWidth - 1);
161 const int nTop ((rPageObjectSize.Height() - nPreviewHeight)/2);
162 return Rectangle(
163 nLeft,
164 nTop,
165 nLeft + nPreviewWidth,
166 nTop + nPreviewHeight);
167 }
168
169
170
171
GetBoundingBox(const model::SharedPageDescriptor & rpPageDescriptor,const Part ePart,const CoordinateSystem eCoordinateSystem)172 Rectangle PageObjectLayouter::GetBoundingBox (
173 const model::SharedPageDescriptor& rpPageDescriptor,
174 const Part ePart,
175 const CoordinateSystem eCoordinateSystem)
176 {
177 OSL_ASSERT(rpPageDescriptor);
178 Point aLocation (rpPageDescriptor ? rpPageDescriptor->GetLocation() : Point(0,0));
179 return GetBoundingBox(aLocation, ePart, eCoordinateSystem);
180 }
181
182
183
184
GetBoundingBox(const Point & rPageObjectLocation,const Part ePart,const CoordinateSystem eCoordinateSystem)185 Rectangle PageObjectLayouter::GetBoundingBox (
186 const Point& rPageObjectLocation,
187 const Part ePart,
188 const CoordinateSystem eCoordinateSystem)
189 {
190 Rectangle aBoundingBox;
191 switch (ePart)
192 {
193 case FocusIndicator:
194 aBoundingBox = maFocusIndicatorBoundingBox;
195 break;
196
197 case PageObject:
198 case MouseOverIndicator:
199 aBoundingBox = maPageObjectBoundingBox;
200 break;
201
202 case Preview:
203 aBoundingBox = maPreviewBoundingBox;
204 break;
205
206 case PageNumber:
207 aBoundingBox = maPageNumberAreaBoundingBox;
208 break;
209
210 case Name:
211 aBoundingBox = maPageNumberAreaBoundingBox;
212 break;
213
214 case TransitionEffectIndicator:
215 aBoundingBox = maTransitionEffectBoundingBox;
216 break;
217 }
218
219 // Adapt coordinates to the requested coordinate system.
220 Point aLocation (rPageObjectLocation);
221 if (eCoordinateSystem == WindowCoordinateSystem)
222 aLocation += mpWindow->GetMapMode().GetOrigin();
223
224 return Rectangle(
225 aBoundingBox.TopLeft() + aLocation,
226 aBoundingBox.BottomRight() + aLocation);
227 }
228
229
230
231
GetSize(const Part ePart,const CoordinateSystem eCoordinateSystem)232 Size PageObjectLayouter::GetSize (
233 const Part ePart,
234 const CoordinateSystem eCoordinateSystem)
235 {
236 return GetBoundingBox(Point(0,0), ePart, eCoordinateSystem).GetSize();
237 }
238
239
240
241
GetPageNumberAreaSize(const int nPageCount)242 Size PageObjectLayouter::GetPageNumberAreaSize (const int nPageCount)
243 {
244 OSL_ASSERT(mpWindow);
245
246 // Set the correct font.
247 Font aOriginalFont (mpWindow->GetFont());
248 if (mpPageNumberFont)
249 mpWindow->SetFont(*mpPageNumberFont);
250
251 String sPageNumberTemplate;
252 if (nPageCount < 10)
253 sPageNumberTemplate = String::CreateFromAscii("9");
254 else if (nPageCount < 100)
255 sPageNumberTemplate = String::CreateFromAscii("99");
256 else if (nPageCount < 200)
257 // Just for the case that 1 is narrower than 9.
258 sPageNumberTemplate = String::CreateFromAscii("199");
259 else if (nPageCount < 1000)
260 sPageNumberTemplate = String::CreateFromAscii("999");
261 else
262 sPageNumberTemplate = String::CreateFromAscii("9999");
263 // More than 9999 pages are not handled.
264
265 const Size aSize (
266 mpWindow->GetTextWidth(sPageNumberTemplate),
267 mpWindow->GetTextHeight());
268
269 mpWindow->SetFont(aOriginalFont);
270
271 return aSize;
272 }
273
274
275
276
GetTransitionEffectIcon(void) const277 Image PageObjectLayouter::GetTransitionEffectIcon (void) const
278 {
279 return maTransitionEffectIcon;
280 }
281
282
283 } } } // end of namespace ::sd::slidesorter::view
284