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