Branch data Line data Source code
1 : : /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 : : /*************************************************************************
3 : : *
4 : : * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
5 : : *
6 : : * Copyright 2000, 2010 Oracle and/or its affiliates.
7 : : *
8 : : * OpenOffice.org - a multi-platform office productivity suite
9 : : *
10 : : * This file is part of OpenOffice.org.
11 : : *
12 : : * OpenOffice.org is free software: you can redistribute it and/or modify
13 : : * it under the terms of the GNU Lesser General Public License version 3
14 : : * only, as published by the Free Software Foundation.
15 : : *
16 : : * OpenOffice.org is distributed in the hope that it will be useful,
17 : : * but WITHOUT ANY WARRANTY; without even the implied warranty of
18 : : * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19 : : * GNU Lesser General Public License version 3 for more details
20 : : * (a copy is included in the LICENSE file that accompanied this code).
21 : : *
22 : : * You should have received a copy of the GNU Lesser General Public License
23 : : * version 3 along with OpenOffice.org. If not, see
24 : : * <http://www.openoffice.org/license.html>
25 : : * for a copy of the LGPLv3 License.
26 : : *
27 : : ************************************************************************/
28 : :
29 : :
30 : : #include "view/SlsLayouter.hxx"
31 : : #include "model/SlideSorterModel.hxx"
32 : : #include "model/SlsPageDescriptor.hxx"
33 : : #include "Window.hxx"
34 : : #include <rtl/math.hxx>
35 : : #include <basegfx/numeric/ftools.hxx>
36 : :
37 : : namespace sd { namespace slidesorter { namespace view {
38 : :
39 : : class Layouter::Implementation
40 : : {
41 : : public:
42 : : SharedSdWindow mpWindow;
43 : : sal_Int32 mnRequestedLeftBorder;
44 : : sal_Int32 mnRequestedRightBorder;
45 : : sal_Int32 mnRequestedTopBorder;
46 : : sal_Int32 mnRequestedBottomBorder;
47 : : sal_Int32 mnLeftBorder;
48 : : sal_Int32 mnRightBorder;
49 : : sal_Int32 mnTopBorder;
50 : : sal_Int32 mnBottomBorder;
51 : : sal_Int32 mnVerticalGap;
52 : : sal_Int32 mnHorizontalGap;
53 : : Size maMinimalSize;
54 : : Size maPreferredSize;
55 : : Size maMaximalSize;
56 : : sal_Int32 mnMinimalColumnCount;
57 : : sal_Int32 mnMaximalColumnCount;
58 : : sal_Int32 mnPageCount;
59 : : sal_Int32 mnColumnCount;
60 : : sal_Int32 mnRowCount;
61 : : /// The maximum number of columns. Can only be larger than the current
62 : : /// number of columns when there are not enough pages to fill all
63 : : /// available columns.
64 : : sal_Int32 mnMaxColumnCount;
65 : : /// The maximum number of rows. Can only be larger than the current
66 : : /// number of rows when there are not enough pages to fill all available
67 : : /// rows.
68 : : sal_Int32 mnMaxRowCount;
69 : : Size maPageObjectSize;
70 : : ::boost::shared_ptr<PageObjectLayouter> mpPageObjectLayouter;
71 : : ::boost::shared_ptr<view::Theme> mpTheme;
72 : :
73 : : /** Specify how the gap between two page objects is associated with the
74 : : page objects.
75 : : */
76 : : enum GapMembership {
77 : : GM_NONE, // Gap is not associated with any page object.
78 : : GM_PREVIOUS, // The whole gap is associated with the previous page
79 : : // object (left or above the gap.)
80 : : GM_BOTH, // Half of the gap is associated with previous, half
81 : : // with the next page object.
82 : : GM_NEXT, // The whole gap is associated with the next page
83 : : // object (right or below the gap.)
84 : : GM_PAGE_BORDER
85 : : };
86 : :
87 : : static Implementation* Create (
88 : : const Implementation& rImplementation,
89 : : const Layouter::Orientation eOrientation);
90 : :
91 : : virtual Layouter::Orientation GetOrientation (void) const = 0;
92 : :
93 : : bool Rearrange (
94 : : const Size& rWindowSize,
95 : : const Size& rPreviewModelSize,
96 : : const sal_uInt32 nPageCount);
97 : :
98 : : /** Calculate the row that the point with the given vertical coordinate
99 : : is over. The horizontal component is ignored.
100 : : @param nYPosition
101 : : Vertical position in model coordinates.
102 : : @param bIncludeBordersAndGaps
103 : : When this flag is <TRUE/> then the area of borders and gaps are
104 : : interpreted as belonging to one of the rows.
105 : : @param eGapMembership
106 : : Specifies to what row the gap areas belong. Here GM_NONE
107 : : corresponds to bIncludeBordersAndGaps being <FALSE/>. When
108 : : GM_BOTH is given then the upper half is associated to the row
109 : : above and the lower half to the row below. Values of
110 : : GM_PREVIOUS and GM_NEXT associate the whole gap area with the
111 : : row above or below respectively.
112 : : */
113 : : sal_Int32 GetRowAtPosition (
114 : : sal_Int32 nYPosition,
115 : : bool bIncludeBordersAndGaps,
116 : : GapMembership eGapMembership = GM_NONE) const;
117 : :
118 : : /** Calculate the column that the point with the given horizontal
119 : : coordinate is over. The verical component is ignored.
120 : : @param nXPosition
121 : : Horizontal position in model coordinates.
122 : : @param bIncludeBordersAndGaps
123 : : When this flag is <TRUE/> then the area of borders and gaps are
124 : : interpreted as belonging to one of the columns.
125 : : @param eGapMembership
126 : : Specifies to what column the gap areas belong.
127 : : */
128 : : sal_Int32 GetColumnAtPosition (
129 : : sal_Int32 nXPosition,
130 : : bool bIncludeBordersAndGaps,
131 : : GapMembership eGapMembership = GM_NONE) const;
132 : :
133 : : /** This method is typically called from GetRowAtPosition() and
134 : : GetColumnAtPosition() to handle a position that lies inside the gap
135 : : between two adjacent rows or columns.
136 : : @param nDistanceIntoGap
137 : : Vertical distance from the bottom of the upper row down into the
138 : : gap or or horizontal distance from the right edge right into the
139 : : gap.
140 : : @param eGapMemberhship
141 : : This value decides what areas in the gap belong to which (or no)
142 : : row or column.
143 : : @param nIndex
144 : : The row index of the upper row or the column index of the left
145 : : column.
146 : : @param nGap
147 : : Width or height of the gap in model coordiantes between the
148 : : page borders.
149 : : @return
150 : : Returns either the index of the upper row (as given as nRow), the
151 : : index of the lower row (nRow+1) or -1 to indicate that the
152 : : position belongs to no row.
153 : : */
154 : : sal_Int32 ResolvePositionInGap (
155 : : sal_Int32 nDistanceIntoGap,
156 : : GapMembership eGapMembership,
157 : : sal_Int32 nIndex,
158 : : sal_Int32 nGap) const;
159 : :
160 : : /** Calculate the logical part of the insert position, i.e. the page
161 : : after whicht to insert.
162 : : */
163 : : virtual void CalculateLogicalInsertPosition (
164 : : const Point& rModelPosition,
165 : : InsertPosition& rPosition) const = 0;
166 : :
167 : : /** Calculate the geometrical part of the insert position, i.e. the
168 : : location of where to display the insertion indicator and the
169 : : distances about which the leading and trailing pages have to be
170 : : moved to make room for the indicator.
171 : : */
172 : : void CalculateGeometricPosition (
173 : : InsertPosition& rPosition,
174 : : const Size& rIndicatorSize,
175 : : const bool bIsVertical,
176 : : model::SlideSorterModel& rModel) const;
177 : :
178 : : /** Return the bounding box of the preview or, when selected, of the page
179 : : object. Thus, it returns something like a visual bounding box.
180 : : */
181 : : Rectangle GetInnerBoundingBox (
182 : : model::SlideSorterModel& rModel,
183 : : const sal_Int32 nIndex) const;
184 : :
185 : : Range GetValidHorizontalSizeRange (void) const;
186 : : Range GetValidVerticalSizeRange (void) const;
187 : :
188 : : Range GetRangeOfVisiblePageObjects (const Rectangle& aVisibleArea) const;
189 : : sal_Int32 GetIndex (
190 : : const sal_Int32 nRow,
191 : : const sal_Int32 nColumn,
192 : : const bool bClampToValidRange) const;
193 : :
194 : : Rectangle GetPageObjectBox (
195 : : const sal_Int32 nIndex,
196 : : const bool bIncludeBorderAndGap = false) const;
197 : :
198 : : Rectangle GetPageObjectBox (
199 : : const sal_Int32 nRow,
200 : : const sal_Int32 nColumn) const;
201 : :
202 : : Rectangle AddBorderAndGap (
203 : : const Rectangle& rBoundingBox,
204 : : const sal_Int32 nRow,
205 : : const sal_Int32 nColumn) const;
206 : :
207 : : Rectangle GetTotalBoundingBox (void) const;
208 : :
209 : : virtual ~Implementation (void);
210 : :
211 : : protected:
212 : : Implementation (
213 : : const SharedSdWindow& rpWindow,
214 : : const ::boost::shared_ptr<view::Theme>& rpTheme);
215 : : Implementation (const Implementation& rImplementation);
216 : :
217 : : virtual void CalculateRowAndColumnCount (const Size& rWindowSize) = 0;
218 : : virtual void CalculateMaxRowAndColumnCount (const Size& rWindowSize) = 0;
219 : : virtual Size CalculateTargetSize (
220 : : const Size& rWindowSize,
221 : : const Size& rPreviewModelSize) const = 0;
222 : : Size GetTargetSize (
223 : : const Size& rWindowSize,
224 : : const Size& rPreviewModelSize,
225 : : const bool bCalculateWidth,
226 : : const bool bCalculateHeight) const;
227 : : void CalculateVerticalLogicalInsertPosition (
228 : : const Point& rModelPosition,
229 : : InsertPosition& rPosition) const;
230 : : };
231 : :
232 : :
233 : : /** The vertical layouter has one column and as many rows as there are
234 : : pages.
235 : : */
236 [ - + ]: 252 : class VerticalImplementation : public Layouter::Implementation
237 : : {
238 : : public:
239 : : VerticalImplementation (
240 : : const SharedSdWindow& rpWindow,
241 : : const ::boost::shared_ptr<view::Theme>& rpTheme);
242 : : VerticalImplementation (const Implementation& rImplementation);
243 : :
244 : : virtual Layouter::Orientation GetOrientation (void) const;
245 : :
246 : : void CalculateLogicalInsertPosition (
247 : : const Point& rModelPosition,
248 : : InsertPosition& rPosition) const;
249 : :
250 : : protected:
251 : : virtual void CalculateRowAndColumnCount (const Size& rWindowSize);
252 : : virtual void CalculateMaxRowAndColumnCount (const Size& rWindowSize);
253 : : virtual Size CalculateTargetSize (
254 : : const Size& rWindowSize,
255 : : const Size& rPreviewModelSize) const;
256 : : };
257 : :
258 : :
259 : : /** The horizontal layouter has one row and as many columns as there are
260 : : pages.
261 : : */
262 [ # # ]: 0 : class HorizontalImplementation : public Layouter::Implementation
263 : : {
264 : : public:
265 : : HorizontalImplementation (const Implementation& rImplementation);
266 : :
267 : : virtual Layouter::Orientation GetOrientation (void) const;
268 : :
269 : : void CalculateLogicalInsertPosition (
270 : : const Point& rModelPosition,
271 : : InsertPosition& rPosition) const;
272 : :
273 : : protected:
274 : : virtual void CalculateRowAndColumnCount (const Size& rWindowSize);
275 : : virtual void CalculateMaxRowAndColumnCount (const Size& rWindowSize);
276 : : virtual Size CalculateTargetSize (
277 : : const Size& rWindowSize,
278 : : const Size& rPreviewModelSize) const;
279 : : };
280 : :
281 : :
282 : : /** The number of columns of the grid layouter is defined via a control in
283 : : the slide sorter tool bar. The number of rows is calculated from the
284 : : number of columns and the number of pages.
285 : : */
286 [ - + ]: 512 : class GridImplementation : public Layouter::Implementation
287 : : {
288 : : public:
289 : : GridImplementation (
290 : : const SharedSdWindow& rpWindow,
291 : : const ::boost::shared_ptr<view::Theme>& rpTheme);
292 : : GridImplementation (const Implementation& rImplementation);
293 : :
294 : : virtual Layouter::Orientation GetOrientation (void) const;
295 : :
296 : : void CalculateLogicalInsertPosition (
297 : : const Point& rModelPosition,
298 : : InsertPosition& rPosition) const;
299 : :
300 : : protected:
301 : : virtual void CalculateRowAndColumnCount (const Size& rWindowSize);
302 : : virtual void CalculateMaxRowAndColumnCount (const Size& rWindowSize);
303 : : virtual Size CalculateTargetSize (
304 : : const Size& rWindowSize,
305 : : const Size& rPreviewModelSize) const;
306 : : };
307 : :
308 : :
309 : :
310 : :
311 : : //===== Layouter ==============================================================
312 : :
313 : 130 : Layouter::Layouter (
314 : : const SharedSdWindow& rpWindow,
315 : : const ::boost::shared_ptr<Theme>& rpTheme)
316 [ + - ]: 130 : : mpImplementation(new GridImplementation(rpWindow, rpTheme)),
317 [ + - ]: 260 : mpWindow(rpWindow)
318 : : {
319 : 130 : }
320 : :
321 : :
322 : :
323 : :
324 [ + - ]: 130 : Layouter::~Layouter (void)
325 : : {
326 : 130 : }
327 : :
328 : :
329 : :
330 : :
331 : 1864 : ::boost::shared_ptr<PageObjectLayouter> Layouter::GetPageObjectLayouter (void) const
332 : : {
333 : 1864 : return mpImplementation->mpPageObjectLayouter;
334 : : }
335 : :
336 : :
337 : :
338 : :
339 : 0 : void Layouter::SetColumnCount (
340 : : sal_Int32 nMinimalColumnCount,
341 : : sal_Int32 nMaximalColumnCount)
342 : : {
343 [ # # ]: 0 : if (nMinimalColumnCount <= nMaximalColumnCount)
344 : : {
345 : 0 : mpImplementation->mnMinimalColumnCount = nMinimalColumnCount;
346 : 0 : mpImplementation->mnMaximalColumnCount = nMaximalColumnCount;
347 : : }
348 : 0 : }
349 : :
350 : :
351 : :
352 : :
353 : 644 : bool Layouter::Rearrange (
354 : : const Orientation eOrientation,
355 : : const Size& rWindowSize,
356 : : const Size& rPageSize,
357 : : const sal_uInt32 nPageCount)
358 : : {
359 : : OSL_ASSERT(mpWindow);
360 : :
361 [ + + ]: 644 : if (eOrientation != mpImplementation->GetOrientation())
362 : 252 : mpImplementation.reset(Implementation::Create(*mpImplementation, eOrientation));
363 : :
364 : 644 : return mpImplementation->Rearrange(rWindowSize, rPageSize, nPageCount);
365 : : }
366 : :
367 : 405 : sal_Int32 Layouter::GetColumnCount (void) const
368 : : {
369 : 405 : return mpImplementation->mnColumnCount;
370 : : }
371 : :
372 : :
373 : :
374 : :
375 : 0 : sal_Int32 Layouter::GetIndex (const sal_Int32 nRow, const sal_Int32 nColumn) const
376 : : {
377 : 0 : return mpImplementation->GetIndex(nRow,nColumn,true);
378 : : }
379 : :
380 : :
381 : :
382 : :
383 : 130 : Size Layouter::GetPageObjectSize (void) const
384 : : {
385 : 130 : return mpImplementation->maPageObjectSize;
386 : : }
387 : :
388 : :
389 : :
390 : :
391 : 1066 : Rectangle Layouter::GetPageObjectBox (
392 : : const sal_Int32 nIndex,
393 : : const bool bIncludeBorderAndGap) const
394 : : {
395 : 1066 : return mpImplementation->GetPageObjectBox(nIndex, bIncludeBorderAndGap);
396 : : }
397 : :
398 : :
399 : :
400 : :
401 : 1938 : Rectangle Layouter::GetTotalBoundingBox (void) const
402 : : {
403 : 1938 : return mpImplementation->GetTotalBoundingBox();
404 : : }
405 : :
406 : :
407 : :
408 : :
409 : 0 : InsertPosition Layouter::GetInsertPosition (
410 : : const Point& rModelPosition,
411 : : const Size& rIndicatorSize,
412 : : model::SlideSorterModel& rModel) const
413 : : {
414 : 0 : InsertPosition aPosition;
415 : 0 : mpImplementation->CalculateLogicalInsertPosition(
416 : : rModelPosition,
417 : 0 : aPosition);
418 : : mpImplementation->CalculateGeometricPosition(
419 : : aPosition,
420 : : rIndicatorSize,
421 : 0 : GetColumnCount()==1,
422 : 0 : rModel);
423 : 0 : return aPosition;
424 : : }
425 : :
426 : :
427 : :
428 : :
429 : 126 : Range Layouter::GetValidHorizontalSizeRange (void) const
430 : : {
431 : 126 : return mpImplementation->GetValidHorizontalSizeRange();
432 : : }
433 : :
434 : :
435 : :
436 : :
437 : 0 : Range Layouter::GetValidVerticalSizeRange (void) const
438 : : {
439 : 0 : return mpImplementation->GetValidVerticalSizeRange();
440 : : }
441 : :
442 : :
443 : :
444 : :
445 : 804 : Range Layouter::GetRangeOfVisiblePageObjects (const Rectangle& aVisibleArea) const
446 : : {
447 : 804 : return mpImplementation->GetRangeOfVisiblePageObjects(aVisibleArea);
448 : : }
449 : :
450 : :
451 : :
452 : :
453 : 126 : sal_Int32 Layouter::GetIndexAtPoint (
454 : : const Point& rPosition,
455 : : const bool bIncludePageBorders,
456 : : const bool bClampToValidRange) const
457 : : {
458 : : const sal_Int32 nRow (
459 : : mpImplementation->GetRowAtPosition (
460 : : rPosition.Y(),
461 : : bIncludePageBorders,
462 [ - + ]: 126 : bIncludePageBorders ? Implementation::GM_PAGE_BORDER : Implementation::GM_NONE));
463 : : const sal_Int32 nColumn (
464 : : mpImplementation->GetColumnAtPosition (
465 : : rPosition.X(),
466 : : bIncludePageBorders,
467 [ - + ]: 126 : bIncludePageBorders ? Implementation::GM_PAGE_BORDER : Implementation::GM_NONE));
468 : :
469 : 126 : return mpImplementation->GetIndex(nRow,nColumn,bClampToValidRange);
470 : : }
471 : :
472 : :
473 : :
474 : :
475 : : //===== Layouter::Implementation ==============================================
476 : :
477 : 252 : Layouter::Implementation* Layouter::Implementation::Create (
478 : : const Implementation& rImplementation,
479 : : const Layouter::Orientation eOrientation)
480 : : {
481 [ - + + ]: 252 : switch (eOrientation)
482 : : {
483 [ # # ]: 0 : case HORIZONTAL: return new HorizontalImplementation(rImplementation);
484 [ + - ]: 126 : case VERTICAL: return new VerticalImplementation(rImplementation);
485 : : case GRID:
486 [ + - ]: 252 : default: return new GridImplementation(rImplementation);
487 : : }
488 : : }
489 : :
490 : :
491 : :
492 : :
493 : 130 : Layouter::Implementation::Implementation (
494 : : const SharedSdWindow& rpWindow,
495 : : const ::boost::shared_ptr<view::Theme>& rpTheme)
496 : : : mpWindow(rpWindow),
497 : : mnRequestedLeftBorder(5),
498 : : mnRequestedRightBorder(5),
499 : : mnRequestedTopBorder(5),
500 : : mnRequestedBottomBorder(5),
501 : : mnLeftBorder(5),
502 : : mnRightBorder(5),
503 : : mnTopBorder(5),
504 : : mnBottomBorder(5),
505 : : mnVerticalGap (10 - 2*Theme_FocusIndicatorWidth),
506 : : mnHorizontalGap(10 - 2*Theme_FocusIndicatorWidth),
507 : : maMinimalSize(132,98),
508 : : maPreferredSize(200,150),
509 : : maMaximalSize(300,200),
510 : : mnMinimalColumnCount(1),
511 : : mnMaximalColumnCount(15),
512 : : mnPageCount(0),
513 : : mnColumnCount(1),
514 : : mnRowCount(0),
515 : : mnMaxColumnCount(0),
516 : : mnMaxRowCount(0),
517 : : maPageObjectSize(1,1),
518 : : mpPageObjectLayouter(),
519 [ + - ][ + - ]: 130 : mpTheme(rpTheme)
520 : : {
521 : 130 : }
522 : :
523 : :
524 : :
525 : :
526 : 252 : Layouter::Implementation::Implementation (const Implementation& rImplementation)
527 : : : mpWindow(rImplementation.mpWindow),
528 : : mnRequestedLeftBorder(rImplementation.mnRequestedLeftBorder),
529 : : mnRequestedRightBorder(rImplementation.mnRequestedRightBorder),
530 : : mnRequestedTopBorder(rImplementation.mnRequestedTopBorder),
531 : : mnRequestedBottomBorder(rImplementation.mnRequestedBottomBorder),
532 : : mnLeftBorder(rImplementation.mnLeftBorder),
533 : : mnRightBorder(rImplementation.mnRightBorder),
534 : : mnTopBorder(rImplementation.mnTopBorder),
535 : : mnBottomBorder(rImplementation.mnBottomBorder),
536 : : mnVerticalGap(rImplementation.mnVerticalGap),
537 : : mnHorizontalGap(rImplementation.mnHorizontalGap),
538 : : maMinimalSize(rImplementation.maMinimalSize),
539 : : maPreferredSize(rImplementation.maPreferredSize),
540 : : maMaximalSize(rImplementation.maMaximalSize),
541 : : mnMinimalColumnCount(rImplementation.mnMinimalColumnCount),
542 : : mnMaximalColumnCount(rImplementation.mnMaximalColumnCount),
543 : : mnPageCount(rImplementation.mnPageCount),
544 : : mnColumnCount(rImplementation.mnColumnCount),
545 : : mnRowCount(rImplementation.mnRowCount),
546 : : mnMaxColumnCount(rImplementation.mnMaxColumnCount),
547 : : mnMaxRowCount(rImplementation.mnMaxRowCount),
548 : : maPageObjectSize(rImplementation.maPageObjectSize),
549 : : mpPageObjectLayouter(),
550 [ + - ][ + - ]: 252 : mpTheme(rImplementation.mpTheme)
551 : : {
552 : 252 : }
553 : :
554 : :
555 : :
556 : :
557 [ + - ][ + - ]: 382 : Layouter::Implementation::~Implementation (void)
558 : : {
559 [ - + ]: 382 : }
560 : :
561 : :
562 : :
563 : :
564 : 644 : bool Layouter::Implementation::Rearrange (
565 : : const Size& rWindowSize,
566 : : const Size& rPreviewModelSize,
567 : : const sal_uInt32 nPageCount)
568 : : {
569 : 644 : mnPageCount = nPageCount;
570 : :
571 : : // Return early when the window or the model have not yet been initialized.
572 [ + - ][ - + ]: 644 : if (rWindowSize.Width()<=0 || rWindowSize.Height()<=0)
[ - + ]
573 : 0 : return false;
574 [ + - ][ - + ]: 644 : if (rPreviewModelSize.Width()<=0 || rPreviewModelSize.Height()<=0)
[ - + ]
575 : 0 : return false;
576 : :
577 : 644 : CalculateRowAndColumnCount(rWindowSize);
578 : :
579 : : // Update the border values.
580 : 644 : mnLeftBorder = mnRequestedLeftBorder;
581 : 644 : mnTopBorder = mnRequestedTopBorder;
582 : 644 : mnRightBorder = mnRequestedRightBorder;
583 : 644 : mnBottomBorder = mnRequestedBottomBorder;
584 [ - + ]: 644 : if (mnColumnCount > 1)
585 : : {
586 : 0 : int nMinimumBorderWidth = mnHorizontalGap/2;
587 [ # # ]: 0 : if (mnLeftBorder < nMinimumBorderWidth)
588 : 0 : mnLeftBorder = nMinimumBorderWidth;
589 [ # # ]: 0 : if (mnRightBorder < nMinimumBorderWidth)
590 : 0 : mnRightBorder = nMinimumBorderWidth;
591 : : }
592 : : else
593 : : {
594 : 644 : int nMinimumBorderHeight = mnVerticalGap/2;
595 [ - + ]: 644 : if (mnTopBorder < nMinimumBorderHeight)
596 : 0 : mnTopBorder = nMinimumBorderHeight;
597 [ - + ]: 644 : if (mnBottomBorder < nMinimumBorderHeight)
598 : 0 : mnBottomBorder = nMinimumBorderHeight;
599 : : }
600 : :
601 : : mpPageObjectLayouter.reset(
602 : : new PageObjectLayouter(
603 : 644 : CalculateTargetSize(rWindowSize, rPreviewModelSize),
604 : : rPreviewModelSize,
605 : : mpWindow,
606 [ + - ][ + - ]: 644 : mnPageCount));
[ + - ]
607 : : maPageObjectSize = mpPageObjectLayouter->GetSize(
608 : : PageObjectLayouter::FocusIndicator,
609 : 644 : PageObjectLayouter::WindowCoordinateSystem);
610 : :
611 : 644 : CalculateMaxRowAndColumnCount(rWindowSize);
612 : :
613 : 644 : return true;
614 : : }
615 : :
616 : :
617 : :
618 : :
619 : 1734 : sal_Int32 Layouter::Implementation::GetRowAtPosition (
620 : : sal_Int32 nYPosition,
621 : : bool bIncludeBordersAndGaps,
622 : : GapMembership eGapMembership) const
623 : : {
624 : 1734 : sal_Int32 nRow = -1;
625 : :
626 : 1734 : const sal_Int32 nY = nYPosition - mnTopBorder;
627 [ + + ]: 1734 : if (nY >= 0)
628 : : {
629 : : // Vertical distance from one row to the next.
630 : 1086 : const sal_Int32 nRowOffset (maPageObjectSize.Height() + mnVerticalGap);
631 : :
632 : : // Calculate row consisting of page objects and gap below.
633 : 1086 : nRow = nY / nRowOffset;
634 : :
635 : 1086 : const sal_Int32 nDistanceIntoGap ((nY - nRow*nRowOffset) - maPageObjectSize.Height());
636 : : // When inside the gap below then nYPosition is not over a page
637 : : // object.
638 [ - + ]: 1086 : if (nDistanceIntoGap > 0)
639 : : nRow = ResolvePositionInGap (
640 : : nDistanceIntoGap,
641 : : eGapMembership,
642 : : nRow,
643 : 0 : mnVerticalGap);
644 : : }
645 [ + + ]: 648 : else if (bIncludeBordersAndGaps)
646 : : {
647 : : // We are in the top border area. Set nRow to the first row when
648 : : // the top border shall be considered to belong to the first row.
649 : 522 : nRow = 0;
650 : : }
651 : :
652 : 1734 : return nRow;
653 : : }
654 : :
655 : :
656 : :
657 : :
658 : 1734 : sal_Int32 Layouter::Implementation::GetColumnAtPosition (
659 : : sal_Int32 nXPosition,
660 : : bool bIncludeBordersAndGaps,
661 : : GapMembership eGapMembership) const
662 : : {
663 : 1734 : sal_Int32 nColumn = -1;
664 : :
665 : 1734 : sal_Int32 nX = nXPosition - mnLeftBorder;
666 [ + + ]: 1734 : if (nX >= 0)
667 : : {
668 : : // Horizontal distance from one column to the next.
669 : 1086 : const sal_Int32 nColumnOffset (maPageObjectSize.Width() + mnHorizontalGap);
670 : :
671 : : // Calculate row consisting of page objects and gap below.
672 : 1086 : nColumn = nX / nColumnOffset;
673 [ - + ]: 1086 : if (nColumn < 0)
674 : 0 : nColumn = 0;
675 [ + + ]: 1086 : else if (nColumn >= mnColumnCount)
676 : 522 : nColumn = mnColumnCount-1;
677 : :
678 : 1086 : const sal_Int32 nDistanceIntoGap ((nX - nColumn*nColumnOffset) - maPageObjectSize.Width());
679 : : // When inside the gap at the right then nXPosition is not over a
680 : : // page object.
681 [ + + ]: 1086 : if (nDistanceIntoGap > 0)
682 : : nColumn = ResolvePositionInGap (
683 : : nDistanceIntoGap,
684 : : eGapMembership,
685 : : nColumn,
686 : 522 : mnHorizontalGap);
687 : : }
688 [ + + ]: 648 : else if (bIncludeBordersAndGaps)
689 : : {
690 : : // We are in the left border area. Set nColumn to the first column
691 : : // when the left border shall be considered to belong to the first
692 : : // column.
693 : 522 : nColumn = 0;
694 : : }
695 : 1734 : return nColumn;
696 : : }
697 : :
698 : :
699 : :
700 : :
701 : 522 : sal_Int32 Layouter::Implementation::ResolvePositionInGap (
702 : : sal_Int32 nDistanceIntoGap,
703 : : GapMembership eGapMembership,
704 : : sal_Int32 nIndex,
705 : : sal_Int32 nGap) const
706 : : {
707 [ - - + - : 522 : switch (eGapMembership)
- - ]
708 : : {
709 : : case GM_NONE:
710 : : // The gap is no man's land.
711 : 0 : nIndex = -1;
712 : 0 : break;
713 : :
714 : : case GM_BOTH:
715 : : {
716 : : // The lower half of the gap belongs to the next row or column.
717 : 0 : sal_Int32 nFirstHalfGapWidth = nGap / 2;
718 [ # # ]: 0 : if (nDistanceIntoGap > nFirstHalfGapWidth)
719 : 0 : nIndex ++;
720 : 0 : break;
721 : : }
722 : :
723 : : case GM_PREVIOUS:
724 : : // Row or column already at correct value.
725 : 522 : break;
726 : :
727 : : case GM_NEXT:
728 : : // The complete gap belongs to the next row or column.
729 : 0 : nIndex ++;
730 : 0 : break;
731 : :
732 : : case GM_PAGE_BORDER:
733 [ # # ]: 0 : if (nDistanceIntoGap > 0)
734 : : {
735 [ # # ]: 0 : if (nDistanceIntoGap > nGap)
736 : : {
737 : : // Inside the border of the next row or column.
738 : 0 : nIndex ++;
739 : : }
740 : : else
741 : : {
742 : : // Inside the gap between the page borders.
743 : 0 : nIndex = -1;
744 : : }
745 : : }
746 : 0 : break;
747 : :
748 : : default:
749 : 0 : nIndex = -1;
750 : : }
751 : :
752 : 522 : return nIndex;
753 : : }
754 : :
755 : :
756 : :
757 : :
758 : 0 : void Layouter::Implementation::CalculateGeometricPosition (
759 : : InsertPosition& rPosition,
760 : : const Size& rIndicatorSize,
761 : : const bool bIsVertical,
762 : : model::SlideSorterModel& rModel) const
763 : : {
764 : : // 1. Determine right/bottom of the leading page and the left/top of the
765 : : // trailing page object and how to distribute the missing space.
766 : 0 : sal_Int32 nLeadingLocation (0);
767 : 0 : sal_Int32 nTrailingLocation (0);
768 : 0 : bool bIsLeadingFixed (false);
769 : 0 : bool bIsTrailingFixed (false);
770 : 0 : sal_Int32 nSecondaryLocation (0);
771 : 0 : const sal_Int32 nIndex (rPosition.GetIndex());
772 : :
773 [ # # ]: 0 : if (rPosition.IsAtRunStart())
774 : : {
775 : : // Place indicator at the top of the column.
776 [ # # ]: 0 : const Rectangle aOuterBox (GetPageObjectBox(nIndex));
777 [ # # ]: 0 : const Rectangle aInnerBox (GetInnerBoundingBox(rModel, nIndex));
778 [ # # ]: 0 : if (bIsVertical)
779 : : {
780 : 0 : nLeadingLocation = aOuterBox.Top();
781 : 0 : nTrailingLocation = aInnerBox.Top();
782 [ # # ]: 0 : nSecondaryLocation = aInnerBox.Center().X();
783 : : }
784 : : else
785 : : {
786 : 0 : nLeadingLocation = aOuterBox.Left();
787 : 0 : nTrailingLocation = aInnerBox.Left();
788 [ # # ]: 0 : nSecondaryLocation = aInnerBox.Center().Y();
789 : : }
790 : 0 : bIsLeadingFixed = true;
791 : : }
792 [ # # ]: 0 : else if (rPosition.IsAtRunEnd())
793 : : {
794 : : // Place indicator at the bottom/right of the column/row.
795 : :
796 [ # # ]: 0 : const Rectangle aOuterBox (GetPageObjectBox(nIndex-1));
797 [ # # ]: 0 : const Rectangle aInnerBox (GetInnerBoundingBox(rModel, nIndex-1));
798 [ # # ]: 0 : if (bIsVertical)
799 : : {
800 : 0 : nLeadingLocation = aInnerBox.Bottom();
801 : 0 : nTrailingLocation = aOuterBox.Bottom();
802 [ # # ]: 0 : nSecondaryLocation = aInnerBox.Center().X();
803 : : }
804 : : else
805 : : {
806 : 0 : nLeadingLocation = aInnerBox.Right();
807 : 0 : nTrailingLocation = aOuterBox.Right();
808 [ # # ]: 0 : nSecondaryLocation = aInnerBox.Center().Y();
809 : : }
810 : 0 : bIsTrailingFixed = true;
811 [ # # ]: 0 : if ( ! rPosition.IsExtraSpaceNeeded())
812 : 0 : bIsLeadingFixed = true;
813 : : }
814 : : else
815 : : {
816 : : // Place indicator between two rows/columns.
817 [ # # ]: 0 : const Rectangle aBox1 (GetInnerBoundingBox(rModel, nIndex-1));
818 [ # # ]: 0 : const Rectangle aBox2 (GetInnerBoundingBox(rModel, nIndex));
819 [ # # ]: 0 : if (bIsVertical)
820 : : {
821 : 0 : nLeadingLocation = aBox1.Bottom();
822 : 0 : nTrailingLocation = aBox2.Top();
823 [ # # ][ # # ]: 0 : nSecondaryLocation = (aBox1.Center().X() + aBox2.Center().X()) / 2;
824 : : }
825 : : else
826 : : {
827 : 0 : nLeadingLocation = aBox1.Right();
828 : 0 : nTrailingLocation = aBox2.Left();
829 [ # # ][ # # ]: 0 : nSecondaryLocation = (aBox1.Center().Y() + aBox2.Center().Y()) / 2;
830 : : }
831 : : }
832 : :
833 : : // 2. Calculate the location of the insert indicator and the offsets of
834 : : // leading and trailing pages.
835 : 0 : const sal_Int32 nAvailableSpace (nTrailingLocation - nLeadingLocation);
836 [ # # ]: 0 : const sal_Int32 nRequiredSpace (bIsVertical ? rIndicatorSize.Height():rIndicatorSize.Width());
837 [ # # ]: 0 : const sal_Int32 nMissingSpace (::std::max(sal_Int32(0), nRequiredSpace - nAvailableSpace));
838 : 0 : sal_Int32 nPrimaryLocation (0);
839 : 0 : sal_Int32 nLeadingOffset (0);
840 : 0 : sal_Int32 nTrailingOffset (0);
841 [ # # ]: 0 : if (bIsLeadingFixed)
842 : : {
843 : 0 : nPrimaryLocation = nLeadingLocation + nRequiredSpace/2;
844 [ # # ]: 0 : if ( ! bIsTrailingFixed)
845 : 0 : nTrailingOffset = nMissingSpace;
846 : : }
847 [ # # ]: 0 : else if (bIsTrailingFixed)
848 : : {
849 : 0 : nPrimaryLocation = nTrailingLocation - nRequiredSpace/2;
850 : 0 : nLeadingOffset = -nMissingSpace;
851 : : }
852 : : else
853 : : {
854 : 0 : nPrimaryLocation = (nLeadingLocation + nTrailingLocation) /2;
855 : 0 : nLeadingOffset = -nMissingSpace/2;
856 : 0 : nTrailingOffset = nMissingSpace + nLeadingOffset;
857 : : }
858 : :
859 [ # # ]: 0 : if (bIsVertical)
860 : : {
861 : : rPosition.SetGeometricalPosition(
862 : : Point(nSecondaryLocation, nPrimaryLocation),
863 : : Point(0, nLeadingOffset),
864 : 0 : Point(0, nTrailingOffset));
865 : : }
866 : : else
867 : : {
868 : : rPosition.SetGeometricalPosition(
869 : : Point(nPrimaryLocation, nSecondaryLocation),
870 : : Point(nLeadingOffset, 0),
871 : 0 : Point(nTrailingOffset, 0));
872 : : }
873 : 0 : }
874 : :
875 : :
876 : :
877 : :
878 : 0 : Rectangle Layouter::Implementation::GetInnerBoundingBox (
879 : : model::SlideSorterModel& rModel,
880 : : const sal_Int32 nIndex) const
881 : : {
882 [ # # ]: 0 : model::SharedPageDescriptor pDescriptor (rModel.GetPageDescriptor(nIndex));
883 [ # # ]: 0 : if ( ! pDescriptor)
884 [ # # ]: 0 : return Rectangle();
885 : :
886 [ # # ]: 0 : const Point aLocation (pDescriptor->GetLocation(true));
887 [ # # ][ # # ]: 0 : if (pDescriptor->HasState(model::PageDescriptor::ST_Selected))
888 : : return mpPageObjectLayouter->GetBoundingBox(
889 : : aLocation,
890 : : PageObjectLayouter::PageObject,
891 [ # # ]: 0 : PageObjectLayouter::ModelCoordinateSystem);
892 : : else
893 : : return mpPageObjectLayouter->GetBoundingBox(
894 : : aLocation,
895 : : PageObjectLayouter::Preview,
896 [ # # ][ # # ]: 0 : PageObjectLayouter::ModelCoordinateSystem);
897 : : }
898 : :
899 : :
900 : :
901 : :
902 : 126 : Range Layouter::Implementation::GetValidHorizontalSizeRange (void) const
903 : : {
904 : : return Range(
905 : 126 : mnLeftBorder + maMinimalSize.Width() + mnRightBorder,
906 : 252 : mnLeftBorder + maMaximalSize.Width() + mnRightBorder);
907 : : }
908 : :
909 : :
910 : :
911 : :
912 : 0 : Range Layouter::Implementation::GetValidVerticalSizeRange (void) const
913 : : {
914 : : return Range(
915 : 0 : mnTopBorder + maMinimalSize.Height() + mnBottomBorder,
916 : 0 : mnTopBorder + maMaximalSize.Height() + mnBottomBorder);
917 : : }
918 : :
919 : :
920 : :
921 : :
922 : 804 : Range Layouter::Implementation::GetRangeOfVisiblePageObjects (const Rectangle& aVisibleArea) const
923 : : {
924 : 804 : const sal_Int32 nRow0 (GetRowAtPosition(aVisibleArea.Top(), true, GM_NEXT));
925 : 804 : const sal_Int32 nCol0 (GetColumnAtPosition(aVisibleArea.Left(),true, GM_NEXT));
926 : 804 : const sal_Int32 nRow1 (GetRowAtPosition(aVisibleArea.Bottom(), true, GM_PREVIOUS));
927 : 804 : const sal_Int32 nCol1 (GetColumnAtPosition(aVisibleArea.Right(), true, GM_PREVIOUS));
928 : :
929 : : // When start and end lie in different rows then the range may include
930 : : // slides outside (left or right of) the given area.
931 : 804 : return Range(GetIndex(nRow0,nCol0,true), GetIndex(nRow1,nCol1,true));
932 : : }
933 : :
934 : :
935 : :
936 : :
937 : 644 : Size Layouter::Implementation::GetTargetSize (
938 : : const Size& rWindowSize,
939 : : const Size& rPreviewModelSize,
940 : : const bool bCalculateWidth,
941 : : const bool bCalculateHeight) const
942 : : {
943 : : (void)rPreviewModelSize;
944 : :
945 [ + - ][ - + ]: 644 : if (mnColumnCount<=0 || mnRowCount<=0)
946 : 0 : return maPreferredSize;
947 [ - + ][ # # ]: 644 : if ( ! (bCalculateWidth || bCalculateHeight))
948 : : {
949 : : OSL_ASSERT(bCalculateWidth || bCalculateHeight);
950 : 0 : return maPreferredSize;
951 : : }
952 : :
953 : : // Calculate the width of each page object.
954 : 644 : Size aTargetSize (0,0);
955 [ + - ]: 644 : if (bCalculateWidth)
956 : : aTargetSize.setWidth(
957 : 644 : (rWindowSize.Width() - mnLeftBorder - mnRightBorder
958 : : - (mnColumnCount-1) * mnHorizontalGap)
959 : 644 : / mnColumnCount);
960 [ # # ]: 0 : else if (bCalculateHeight)
961 : : aTargetSize.setHeight(
962 : 0 : (rWindowSize.Height() - mnTopBorder - mnBottomBorder
963 : : - (mnRowCount-1) * mnVerticalGap)
964 : 0 : / mnRowCount);
965 : :
966 [ + - ]: 644 : if (bCalculateWidth)
967 : : {
968 [ - + ]: 644 : if (aTargetSize.Width() < maMinimalSize.Width())
969 : 0 : aTargetSize.setWidth(maMinimalSize.Width());
970 [ - + ]: 644 : else if (aTargetSize.Width() > maMaximalSize.Width())
971 : 0 : aTargetSize.setWidth(maMaximalSize.Width());
972 : : }
973 [ # # ]: 0 : else if (bCalculateHeight)
974 : : {
975 [ # # ]: 0 : if (aTargetSize.Height() < maMinimalSize.Height())
976 : 0 : aTargetSize.setHeight(maMinimalSize.Height());
977 [ # # ]: 0 : else if (aTargetSize.Height() > maMaximalSize.Height())
978 : 0 : aTargetSize.setHeight(maMaximalSize.Height());
979 : : }
980 : :
981 : 644 : return aTargetSize;
982 : : }
983 : :
984 : :
985 : :
986 : :
987 : 1734 : sal_Int32 Layouter::Implementation::GetIndex (
988 : : const sal_Int32 nRow,
989 : : const sal_Int32 nColumn,
990 : : const bool bClampToValidRange) const
991 : : {
992 [ + + ][ + - ]: 1734 : if (nRow >= 0 && nColumn >= 0)
993 : : {
994 : 1608 : const sal_Int32 nIndex (nRow * mnColumnCount + nColumn);
995 [ + + ]: 1608 : if (nIndex >= mnPageCount)
996 [ + - ]: 509 : if (bClampToValidRange)
997 : 509 : return mnPageCount-1;
998 : : else
999 : 0 : return -1;
1000 : : else
1001 : 1099 : return nIndex;
1002 : : }
1003 [ - + ]: 126 : else if (bClampToValidRange)
1004 : 0 : return 0;
1005 : : else
1006 : 1734 : return -1;
1007 : : }
1008 : :
1009 : :
1010 : :
1011 : :
1012 : 1066 : Rectangle Layouter::Implementation::GetPageObjectBox (
1013 : : const sal_Int32 nIndex,
1014 : : const bool bIncludeBorderAndGap) const
1015 : : {
1016 : 1066 : const sal_Int32 nRow (nIndex / mnColumnCount);
1017 : 1066 : const sal_Int32 nColumn (nIndex % mnColumnCount);
1018 : :
1019 [ + - ]: 1066 : const Rectangle aBoundingBox (GetPageObjectBox(nRow,nColumn));
1020 [ + + ]: 1066 : if (bIncludeBorderAndGap)
1021 : 570 : return AddBorderAndGap(aBoundingBox, nRow, nColumn);
1022 : : else
1023 : 1066 : return aBoundingBox;
1024 : : }
1025 : :
1026 : :
1027 : :
1028 : :
1029 : 1066 : Rectangle Layouter::Implementation::GetPageObjectBox (
1030 : : const sal_Int32 nRow,
1031 : : const sal_Int32 nColumn) const
1032 : : {
1033 : : return Rectangle(
1034 : : Point (mnLeftBorder
1035 : 1066 : + nColumn * maPageObjectSize.Width()
1036 : : + (nColumn>0 ? nColumn : 0) * mnHorizontalGap,
1037 : : mnTopBorder
1038 : 1066 : + nRow * maPageObjectSize.Height()
1039 : : + (nRow>0 ? nRow : 0) * mnVerticalGap),
1040 [ + - ]: 1066 : maPageObjectSize);
1041 : : }
1042 : :
1043 : :
1044 : :
1045 : :
1046 : :
1047 : 570 : Rectangle Layouter::Implementation::AddBorderAndGap (
1048 : : const Rectangle& rBoundingBox,
1049 : : const sal_Int32 nRow,
1050 : : const sal_Int32 nColumn) const
1051 : : {
1052 : 570 : Rectangle aBoundingBox (rBoundingBox);
1053 : :
1054 [ + - ]: 570 : if (nColumn == 0)
1055 : 570 : aBoundingBox.Left() = 0;
1056 : : else
1057 : 0 : aBoundingBox.Left() -= mnHorizontalGap/2;
1058 [ + - ]: 570 : if (nColumn == mnColumnCount-1)
1059 : 570 : aBoundingBox.Right() += mnRightBorder;
1060 : : else
1061 : 0 : aBoundingBox.Right() += mnHorizontalGap/2;
1062 [ + + ]: 570 : if (nRow == 0)
1063 : 566 : aBoundingBox.Top() = 0;
1064 : : else
1065 : 4 : aBoundingBox.Top() -= mnVerticalGap/2;
1066 [ + + ]: 570 : if (nRow == mnRowCount-1)
1067 : 270 : aBoundingBox.Bottom() += mnBottomBorder;
1068 : : else
1069 : 300 : aBoundingBox.Bottom() += mnVerticalGap/2;
1070 : 570 : return aBoundingBox;
1071 : : }
1072 : :
1073 : :
1074 : :
1075 : :
1076 : 1938 : Rectangle Layouter::Implementation::GetTotalBoundingBox (void) const
1077 : : {
1078 : 1938 : sal_Int32 nHorizontalSize = 0;
1079 : 1938 : sal_Int32 nVerticalSize = 0;
1080 [ + - ]: 1938 : if (mnColumnCount > 0)
1081 : : {
1082 : 1938 : sal_Int32 nRowCount = (mnPageCount+mnColumnCount-1) / mnColumnCount;
1083 : : nHorizontalSize =
1084 : : mnLeftBorder
1085 : : + mnRightBorder
1086 : 1938 : + mnColumnCount * maPageObjectSize.Width();
1087 [ - + ]: 1938 : if (mnColumnCount > 1)
1088 : 0 : nHorizontalSize += (mnColumnCount-1) * mnHorizontalGap;
1089 : : nVerticalSize =
1090 : : mnTopBorder
1091 : : + mnBottomBorder
1092 : 1938 : + nRowCount * maPageObjectSize.Height();
1093 [ + + ]: 1938 : if (nRowCount > 1)
1094 : 212 : nVerticalSize += (nRowCount-1) * mnVerticalGap;
1095 : : }
1096 : :
1097 : : return Rectangle (
1098 : : Point(0,0),
1099 : : Size (nHorizontalSize, nVerticalSize)
1100 [ + - ]: 1938 : );
1101 : : }
1102 : :
1103 : :
1104 : :
1105 : :
1106 : 0 : void Layouter::Implementation::CalculateVerticalLogicalInsertPosition (
1107 : : const Point& rModelPosition,
1108 : : InsertPosition& rPosition) const
1109 : : {
1110 : 0 : const sal_Int32 nY = rModelPosition.Y() - mnTopBorder + maPageObjectSize.Height()/2;
1111 : 0 : const sal_Int32 nRowHeight (maPageObjectSize.Height() + mnVerticalGap);
1112 [ # # ]: 0 : const sal_Int32 nRow (::std::min(mnPageCount, nY / nRowHeight));
1113 : : rPosition.SetLogicalPosition (
1114 : : nRow,
1115 : : 0,
1116 : : nRow,
1117 : : (nRow == 0),
1118 : : (nRow == mnRowCount),
1119 : 0 : (nRow >= mnMaxRowCount));
1120 : 0 : }
1121 : :
1122 : :
1123 : :
1124 : :
1125 : : //===== HorizontalImplementation ================================================
1126 : :
1127 : 0 : HorizontalImplementation::HorizontalImplementation (const Implementation& rImplementation)
1128 : 0 : : Implementation(rImplementation)
1129 : : {
1130 : 0 : }
1131 : :
1132 : :
1133 : :
1134 : :
1135 : 0 : Layouter::Orientation HorizontalImplementation::GetOrientation (void) const
1136 : : {
1137 : 0 : return Layouter::HORIZONTAL;
1138 : : }
1139 : :
1140 : :
1141 : :
1142 : :
1143 : 0 : void HorizontalImplementation::CalculateRowAndColumnCount (const Size& rWindowSize)
1144 : : {
1145 : : (void)rWindowSize;
1146 : :
1147 : : // Row and column count are fixed (for a given page count.)
1148 : 0 : mnColumnCount = mnPageCount;
1149 : 0 : mnRowCount = 1;
1150 : 0 : }
1151 : :
1152 : :
1153 : :
1154 : :
1155 : 0 : void HorizontalImplementation::CalculateMaxRowAndColumnCount (const Size& rWindowSize)
1156 : : {
1157 : 0 : mnMaxColumnCount = (rWindowSize.Width() - mnLeftBorder - mnRightBorder)
1158 : 0 : / (maPageObjectSize.Width() + mnHorizontalGap);
1159 : 0 : mnMaxRowCount = 1;
1160 : 0 : }
1161 : :
1162 : :
1163 : :
1164 : :
1165 : 0 : Size HorizontalImplementation::CalculateTargetSize (
1166 : : const Size& rWindowSize,
1167 : : const Size& rPreviewModelSize) const
1168 : : {
1169 : 0 : return Implementation::GetTargetSize(rWindowSize, rPreviewModelSize, false, true);
1170 : : }
1171 : :
1172 : :
1173 : :
1174 : :
1175 : 0 : void HorizontalImplementation::CalculateLogicalInsertPosition (
1176 : : const Point& rModelPosition,
1177 : : InsertPosition& rPosition) const
1178 : : {
1179 : 0 : const sal_Int32 nX = rModelPosition.X() - mnLeftBorder + maPageObjectSize.Width()/2;
1180 : 0 : const sal_Int32 nColumnWidth (maPageObjectSize.Width() + mnHorizontalGap);
1181 [ # # ]: 0 : const sal_Int32 nColumn (::std::min(mnPageCount, nX / nColumnWidth));
1182 : : rPosition.SetLogicalPosition (
1183 : : 0,
1184 : : nColumn,
1185 : : nColumn,
1186 : : (nColumn == 0),
1187 : : (nColumn == mnColumnCount),
1188 : 0 : (nColumn >= mnMaxColumnCount));
1189 : 0 : }
1190 : :
1191 : :
1192 : :
1193 : :
1194 : : //===== VerticalImplementation ================================================
1195 : :
1196 : 126 : VerticalImplementation::VerticalImplementation (const Implementation& rImplementation)
1197 : 126 : : Implementation(rImplementation)
1198 : : {
1199 : 126 : }
1200 : :
1201 : :
1202 : :
1203 : :
1204 : 374 : Layouter::Orientation VerticalImplementation::GetOrientation (void) const
1205 : : {
1206 : 374 : return Layouter::VERTICAL;
1207 : : }
1208 : :
1209 : :
1210 : :
1211 : :
1212 : 374 : void VerticalImplementation::CalculateRowAndColumnCount (const Size& rWindowSize)
1213 : : {
1214 : : (void)rWindowSize;
1215 : :
1216 : : // Row and column count are fixed (for a given page count.)
1217 : 374 : mnRowCount = mnPageCount;
1218 : 374 : mnColumnCount = 1;
1219 : :
1220 : 374 : }
1221 : :
1222 : :
1223 : :
1224 : :
1225 : 374 : void VerticalImplementation::CalculateMaxRowAndColumnCount (const Size& rWindowSize)
1226 : : {
1227 : 374 : mnMaxRowCount = (rWindowSize.Height() - mnTopBorder - mnBottomBorder)
1228 : 374 : / (maPageObjectSize.Height() + mnVerticalGap);
1229 : 374 : mnMaxColumnCount = 1;
1230 : 374 : }
1231 : :
1232 : :
1233 : :
1234 : :
1235 : 374 : Size VerticalImplementation::CalculateTargetSize (
1236 : : const Size& rWindowSize,
1237 : : const Size& rPreviewModelSize) const
1238 : : {
1239 : 374 : return Implementation::GetTargetSize(rWindowSize, rPreviewModelSize, true, false);
1240 : : }
1241 : :
1242 : :
1243 : :
1244 : :
1245 : 0 : void VerticalImplementation::CalculateLogicalInsertPosition (
1246 : : const Point& rModelPosition,
1247 : : InsertPosition& rPosition) const
1248 : : {
1249 : 0 : return CalculateVerticalLogicalInsertPosition(rModelPosition, rPosition);
1250 : : }
1251 : :
1252 : :
1253 : :
1254 : :
1255 : : //===== GridImplementation ================================================
1256 : :
1257 : 130 : GridImplementation::GridImplementation (
1258 : : const SharedSdWindow& rpWindow,
1259 : : const ::boost::shared_ptr<view::Theme>& rpTheme)
1260 : 130 : : Implementation(rpWindow, rpTheme)
1261 : : {
1262 : 130 : }
1263 : :
1264 : :
1265 : :
1266 : :
1267 : 126 : GridImplementation::GridImplementation (const Implementation& rImplementation)
1268 : 126 : : Implementation(rImplementation)
1269 : : {
1270 : 126 : }
1271 : :
1272 : :
1273 : :
1274 : :
1275 : 270 : Layouter::Orientation GridImplementation::GetOrientation (void) const
1276 : : {
1277 : 270 : return Layouter::GRID;
1278 : : }
1279 : :
1280 : :
1281 : :
1282 : :
1283 : 270 : void GridImplementation::CalculateRowAndColumnCount (const Size& rWindowSize)
1284 : : {
1285 : : // Calculate the column count.
1286 : : mnColumnCount
1287 : 270 : = (rWindowSize.Width() - mnRequestedLeftBorder - mnRequestedRightBorder)
1288 : 270 : / (maPreferredSize.Width() + mnHorizontalGap);
1289 [ + - ]: 270 : if (mnColumnCount < mnMinimalColumnCount)
1290 : 270 : mnColumnCount = mnMinimalColumnCount;
1291 [ - + ]: 270 : if (mnColumnCount > mnMaximalColumnCount)
1292 : 0 : mnColumnCount = mnMaximalColumnCount;
1293 : 270 : mnRowCount = (mnPageCount + mnColumnCount-1)/mnColumnCount;
1294 : 270 : }
1295 : :
1296 : :
1297 : :
1298 : :
1299 : 270 : void GridImplementation::CalculateMaxRowAndColumnCount (const Size& rWindowSize)
1300 : : {
1301 : 270 : mnMaxColumnCount = (rWindowSize.Width() - mnLeftBorder - mnRightBorder)
1302 : 270 : / (maPageObjectSize.Width() + mnHorizontalGap);
1303 : 270 : mnMaxRowCount = (rWindowSize.Height() - mnTopBorder - mnBottomBorder)
1304 : 270 : / (maPageObjectSize.Height() + mnVerticalGap);
1305 : 270 : }
1306 : :
1307 : :
1308 : :
1309 : :
1310 : :
1311 : 270 : Size GridImplementation::CalculateTargetSize (
1312 : : const Size& rWindowSize,
1313 : : const Size& rPreviewModelSize) const
1314 : : {
1315 : 270 : return Implementation::GetTargetSize(rWindowSize, rPreviewModelSize, true, true);
1316 : : }
1317 : :
1318 : :
1319 : :
1320 : :
1321 : 0 : void GridImplementation::CalculateLogicalInsertPosition (
1322 : : const Point& rModelPosition,
1323 : : InsertPosition& rPosition) const
1324 : : {
1325 [ # # ]: 0 : if (mnColumnCount == 1)
1326 : : {
1327 : 0 : CalculateVerticalLogicalInsertPosition(rModelPosition, rPosition);
1328 : : }
1329 : : else
1330 : : {
1331 : : // Handle the general case of more than one column.
1332 : : sal_Int32 nRow (::std::min(
1333 : : mnRowCount-1,
1334 [ # # ][ # # ]: 0 : GetRowAtPosition (rModelPosition.Y(), true, GM_BOTH)));
1335 : 0 : const sal_Int32 nX = rModelPosition.X() - mnLeftBorder + maPageObjectSize.Width()/2;
1336 : 0 : const sal_Int32 nColumnWidth (maPageObjectSize.Width() + mnHorizontalGap);
1337 [ # # ]: 0 : sal_Int32 nColumn (::std::min(mnColumnCount, nX / nColumnWidth));
1338 : 0 : sal_Int32 nIndex (nRow * mnColumnCount + nColumn);
1339 : 0 : bool bIsAtRunEnd (nColumn == mnColumnCount);
1340 : :
1341 [ # # ]: 0 : if (nIndex >= mnPageCount)
1342 : : {
1343 : 0 : nIndex = mnPageCount;
1344 : 0 : nRow = mnRowCount-1;
1345 [ # # ][ # # ]: 0 : nColumn = ::std::min(::std::min(mnPageCount, mnColumnCount), nColumn);
1346 : 0 : bIsAtRunEnd = true;
1347 : : }
1348 : :
1349 : : rPosition.SetLogicalPosition (
1350 : : nRow,
1351 : : nColumn,
1352 : : nIndex,
1353 : : (nColumn == 0),
1354 : : bIsAtRunEnd,
1355 : 0 : (nColumn >= mnMaxColumnCount));
1356 : : }
1357 : 0 : }
1358 : :
1359 : :
1360 : :
1361 : :
1362 : : //===== InsertPosition ========================================================
1363 : :
1364 : 130 : InsertPosition::InsertPosition (void)
1365 : : : mnRow(-1),
1366 : : mnColumn(-1),
1367 : : mnIndex(-1),
1368 : : mbIsAtRunStart(false),
1369 : : mbIsAtRunEnd(false),
1370 : : mbIsExtraSpaceNeeded(false),
1371 : : maLocation(0,0),
1372 : : maLeadingOffset(0,0),
1373 : 130 : maTrailingOffset(0,0)
1374 : : {
1375 : 130 : }
1376 : :
1377 : :
1378 : :
1379 : :
1380 : 0 : InsertPosition& InsertPosition::operator= (const InsertPosition& rInsertPosition)
1381 : : {
1382 [ # # ]: 0 : if (this != &rInsertPosition)
1383 : : {
1384 : 0 : mnRow = rInsertPosition.mnRow;
1385 : 0 : mnColumn = rInsertPosition.mnColumn;
1386 : 0 : mnIndex = rInsertPosition.mnIndex;
1387 : 0 : mbIsAtRunStart = rInsertPosition.mbIsAtRunStart;
1388 : 0 : mbIsAtRunEnd = rInsertPosition.mbIsAtRunEnd;
1389 : 0 : mbIsExtraSpaceNeeded = rInsertPosition.mbIsExtraSpaceNeeded;
1390 : 0 : maLocation = rInsertPosition.maLocation;
1391 : 0 : maLeadingOffset = rInsertPosition.maLeadingOffset;
1392 : 0 : maTrailingOffset = rInsertPosition.maTrailingOffset;
1393 : : }
1394 : 0 : return *this;
1395 : : }
1396 : :
1397 : :
1398 : :
1399 : :
1400 : 0 : bool InsertPosition::operator== (const InsertPosition& rInsertPosition) const
1401 : : {
1402 : : // Do not compare the geometrical information (maLocation).
1403 : : return mnRow==rInsertPosition.mnRow
1404 : : && mnColumn==rInsertPosition.mnColumn
1405 : : && mnIndex==rInsertPosition.mnIndex
1406 : : && mbIsAtRunStart==rInsertPosition.mbIsAtRunStart
1407 : : && mbIsAtRunEnd==rInsertPosition.mbIsAtRunEnd
1408 [ # # ][ # # ]: 0 : && mbIsExtraSpaceNeeded==rInsertPosition.mbIsExtraSpaceNeeded;
[ # # ][ # # ]
[ # # ][ # # ]
1409 : : }
1410 : :
1411 : :
1412 : :
1413 : :
1414 : 0 : bool InsertPosition::operator!= (const InsertPosition& rInsertPosition) const
1415 : : {
1416 : 0 : return !operator==(rInsertPosition);
1417 : : }
1418 : :
1419 : :
1420 : :
1421 : :
1422 : 0 : void InsertPosition::SetLogicalPosition (
1423 : : const sal_Int32 nRow,
1424 : : const sal_Int32 nColumn,
1425 : : const sal_Int32 nIndex,
1426 : : const bool bIsAtRunStart,
1427 : : const bool bIsAtRunEnd,
1428 : : const bool bIsExtraSpaceNeeded)
1429 : : {
1430 : 0 : mnRow = nRow;
1431 : 0 : mnColumn = nColumn;
1432 : 0 : mnIndex = nIndex;
1433 : 0 : mbIsAtRunStart = bIsAtRunStart;
1434 : 0 : mbIsAtRunEnd = bIsAtRunEnd;
1435 : 0 : mbIsExtraSpaceNeeded = bIsExtraSpaceNeeded;
1436 : 0 : }
1437 : :
1438 : :
1439 : :
1440 : :
1441 : 0 : void InsertPosition::SetGeometricalPosition(
1442 : : const Point aLocation,
1443 : : const Point aLeadingOffset,
1444 : : const Point aTrailingOffset)
1445 : : {
1446 : 0 : maLocation = aLocation;
1447 : 0 : maLeadingOffset = aLeadingOffset;
1448 : 0 : maTrailingOffset = aTrailingOffset;
1449 : 0 : }
1450 : :
1451 : :
1452 : :
1453 : : } } } // end of namespace ::sd::slidesorter::namespace
1454 : :
1455 : : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
|