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 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 99 PageObjectLayouter::~PageObjectLayouter(void) 100 { 101 } 102 103 104 105 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 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 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 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 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 then 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 277 Image PageObjectLayouter::GetTransitionEffectIcon (void) const 278 { 279 return maTransitionEffectIcon; 280 } 281 282 283 } } } // end of namespace ::sd::slidesorter::view 284