cid#1607171 Data race condition
[LibreOffice.git] / sd / source / ui / slidesorter / view / SlsPageObjectLayouter.cxx
blobb26eb0746f301345298c3664a4f71ac24f5211bf
1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 /*
3 * This file is part of the LibreOffice project.
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/.
9 * This file incorporates work covered by the following license notice:
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 .
20 #include <view/SlsPageObjectLayouter.hxx>
22 #include <model/SlsPageDescriptor.hxx>
23 #include <view/SlsTheme.hxx>
24 #include <tools/IconCache.hxx>
25 #include <Window.hxx>
27 #include <bitmaps.hlst>
28 #include <osl/diagnose.h>
30 namespace sd::slidesorter::view {
32 namespace {
33 const sal_Int32 gnLeftPageNumberOffset = 2;
34 const sal_Int32 gnRightPageNumberOffset = 5;
35 const sal_Int32 gnOuterBorderWidth = 5;
36 const sal_Int32 gnInfoAreaMinWidth = 26;
39 PageObjectLayouter::PageObjectLayouter (
40 const Size& rPageObjectWindowSize,
41 const Size& rPageSize,
42 sd::Window *pWindow,
43 const sal_Int32 nPageCount)
44 : mpWindow(pWindow),
45 maTransitionEffectIcon(IconCache::Instance().GetIcon(BMP_FADE_EFFECT_INDICATOR)),
46 maCustomAnimationEffectIcon(IconCache::Instance().GetIcon(BMP_CUSTOM_ANIMATION_INDICATOR)),
47 mpPageNumberFont(Theme::GetFont(Theme::Font_PageNumber, *pWindow->GetOutDev()))
49 const Size aPageNumberAreaSize (GetPageNumberAreaSize(nPageCount));
51 const int nMaximumBorderWidth (gnOuterBorderWidth);
52 const int nFocusIndicatorWidth (Theme_FocusIndicatorWidth);
54 Size aPageObjectSize(rPageObjectWindowSize.Width(), rPageObjectWindowSize.Height());
55 maPreviewBoundingBox = CalculatePreviewBoundingBox(
56 aPageObjectSize,
57 Size(rPageSize.Width(), rPageSize.Height()),
58 aPageNumberAreaSize.Width(),
59 nFocusIndicatorWidth);
60 maFocusIndicatorBoundingBox = ::tools::Rectangle(Point(0,0), aPageObjectSize);
61 maPageObjectBoundingBox = ::tools::Rectangle(
62 Point(
63 nFocusIndicatorWidth,
64 nFocusIndicatorWidth),
65 Size(
66 aPageObjectSize.Width()-2*nFocusIndicatorWidth,
67 aPageObjectSize.Height()-2*nFocusIndicatorWidth));
69 maPageNumberAreaBoundingBox = ::tools::Rectangle(
70 Point(
71 std::max(gnLeftPageNumberOffset,
72 sal_Int32(maPreviewBoundingBox.Left()
73 - gnRightPageNumberOffset
74 - aPageNumberAreaSize.Width())),
75 nMaximumBorderWidth),
76 aPageNumberAreaSize);
78 const Size aIconSize (maTransitionEffectIcon.GetSizePixel());
79 maTransitionEffectBoundingBox = ::tools::Rectangle(
80 Point(
81 (maPreviewBoundingBox.Left() - 2*aIconSize.Width()) / 2,
82 maPreviewBoundingBox.Bottom() - aIconSize.Height()),
83 aIconSize);
84 maCustomAnimationEffectBoundingBox = ::tools::Rectangle(
85 Point(
86 (maPreviewBoundingBox.Left() - 2*aIconSize.Width()) / 2,
87 maPreviewBoundingBox.Bottom() - 2*aIconSize.Height()),
88 aIconSize);
91 PageObjectLayouter::~PageObjectLayouter()
95 ::tools::Rectangle PageObjectLayouter::CalculatePreviewBoundingBox (
96 Size& rPageObjectSize,
97 const Size& rPageSize,
98 const sal_Int32 nPageNumberAreaWidth,
99 const sal_Int32 nFocusIndicatorWidth)
101 const sal_Int32 nIconWidth (maTransitionEffectIcon.GetSizePixel().Width());
102 const sal_Int32 nLeftAreaWidth (
103 ::std::max(
104 gnInfoAreaMinWidth,
105 gnRightPageNumberOffset
106 + ::std::max(
107 nPageNumberAreaWidth,
108 nIconWidth)));
109 sal_Int32 nPreviewWidth;
110 sal_Int32 nPreviewHeight;
111 const double nPageAspectRatio (double(rPageSize.Width()) / double(rPageSize.Height()));
112 if (rPageObjectSize.Height() == 0)
114 // Calculate height so that the preview fills the available
115 // horizontal space completely while observing the aspect ratio of
116 // the preview.
117 nPreviewWidth = rPageObjectSize.Width()
118 - nLeftAreaWidth - gnOuterBorderWidth - 2*nFocusIndicatorWidth - 1;
119 nPreviewHeight = ::basegfx::fround(nPreviewWidth / nPageAspectRatio);
120 rPageObjectSize.setHeight(nPreviewHeight + 2*gnOuterBorderWidth + 2*nFocusIndicatorWidth + 1);
122 else if (rPageObjectSize.Width() == 0)
124 // Calculate the width of the page object so that the preview fills
125 // the available vertical space completely while observing the
126 // aspect ratio of the preview.
127 nPreviewHeight = rPageObjectSize.Height() - 2*gnOuterBorderWidth - 2*nFocusIndicatorWidth - 1;
128 nPreviewWidth = ::basegfx::fround(nPreviewHeight * nPageAspectRatio);
129 rPageObjectSize.setWidth(nPreviewWidth
130 + nLeftAreaWidth + gnOuterBorderWidth + 2*nFocusIndicatorWidth + 1);
133 else
135 // The size of the page object is given. Calculate the size of the
136 // preview.
137 nPreviewWidth = rPageObjectSize.Width()
138 - nLeftAreaWidth - gnOuterBorderWidth - 2*nFocusIndicatorWidth - 1;
139 nPreviewHeight = rPageObjectSize.Height()
140 - gnOuterBorderWidth - 2*nFocusIndicatorWidth - 1;
141 if (double(nPreviewWidth)/double(nPreviewHeight) > nPageAspectRatio)
142 nPreviewWidth = ::basegfx::fround(nPreviewHeight * nPageAspectRatio);
143 else
144 nPreviewHeight = ::basegfx::fround(nPreviewWidth / nPageAspectRatio);
146 // When the preview does not fill the available space completely then
147 // place it flush right and vertically centered.
148 const int nLeft (rPageObjectSize.Width()
149 - gnOuterBorderWidth - nPreviewWidth - nFocusIndicatorWidth - 1);
150 const int nTop ((rPageObjectSize.Height() - nPreviewHeight)/2);
151 return ::tools::Rectangle(
152 nLeft,
153 nTop,
154 nLeft + nPreviewWidth,
155 nTop + nPreviewHeight);
158 ::tools::Rectangle PageObjectLayouter::GetBoundingBox (
159 const model::SharedPageDescriptor& rpPageDescriptor,
160 const Part ePart,
161 const CoordinateSystem eCoordinateSystem,
162 bool bIgnoreLocation)
164 OSL_ASSERT(rpPageDescriptor);
165 Point aLocation(0,0);
166 if (rpPageDescriptor)
167 aLocation = rpPageDescriptor->GetLocation( bIgnoreLocation );
168 return GetBoundingBox(aLocation, ePart, eCoordinateSystem);
171 ::tools::Rectangle PageObjectLayouter::GetBoundingBox (
172 const Point& rPageObjectLocation,
173 const Part ePart,
174 const CoordinateSystem eCoordinateSystem)
176 ::tools::Rectangle aBoundingBox;
177 switch (ePart)
179 case Part::FocusIndicator:
180 aBoundingBox = maFocusIndicatorBoundingBox;
181 break;
183 case Part::PageObject:
184 aBoundingBox = maPageObjectBoundingBox;
185 break;
187 case Part::Preview:
188 aBoundingBox = maPreviewBoundingBox;
189 break;
191 case Part::PageNumber:
192 aBoundingBox = maPageNumberAreaBoundingBox;
193 break;
195 case Part::TransitionEffectIndicator:
196 aBoundingBox = maTransitionEffectBoundingBox;
197 break;
198 case Part::CustomAnimationEffectIndicator:
199 aBoundingBox = maCustomAnimationEffectBoundingBox;
200 break;
203 // Adapt coordinates to the requested coordinate system.
204 Point aLocation (rPageObjectLocation);
205 if (eCoordinateSystem == WindowCoordinateSystem)
206 aLocation += mpWindow->GetMapMode().GetOrigin();
208 return ::tools::Rectangle(
209 aBoundingBox.TopLeft() + aLocation,
210 aBoundingBox.BottomRight() + aLocation);
213 Size PageObjectLayouter::GetPreviewSize ()
215 return GetBoundingBox(Point(0,0), PageObjectLayouter::Part::Preview,
216 WindowCoordinateSystem).GetSize();
219 Size PageObjectLayouter::GetGridMaxSize()
221 return GetBoundingBox(Point(0,0), PageObjectLayouter::Part::FocusIndicator,
222 WindowCoordinateSystem).GetSize();
225 Size PageObjectLayouter::GetPageNumberAreaSize (const int nPageCount)
227 OSL_ASSERT(mpWindow);
229 // Set the correct font.
230 vcl::Font aOriginalFont (mpWindow->GetFont());
231 if (mpPageNumberFont)
232 mpWindow->SetFont(*mpPageNumberFont);
234 OUString sPageNumberTemplate;
235 if (nPageCount < 10)
236 sPageNumberTemplate = "9";
237 else if (nPageCount < 100)
238 sPageNumberTemplate = "99";
239 else if (nPageCount < 200)
240 // Just for the case that 1 is narrower than 9.
241 sPageNumberTemplate = "199";
242 else if (nPageCount < 1000)
243 sPageNumberTemplate = "999";
244 else
245 sPageNumberTemplate = "9999";
246 // More than 9999 pages are not handled.
248 const Size aSize (
249 mpWindow->GetTextWidth(sPageNumberTemplate),
250 mpWindow->GetTextHeight());
252 mpWindow->SetFont(aOriginalFont);
254 return aSize;
257 } // end of namespace ::sd::slidesorter::view
259 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */