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