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