1 /**************************************************************
2  *
3  * Licensed to the Apache Software Foundation (ASF) under one
4  * or more contributor license agreements.  See the NOTICE file
5  * distributed with this work for additional information
6  * regarding copyright ownership.  The ASF licenses this file
7  * to you under the Apache License, Version 2.0 (the
8  * "License"); you may not use this file except in compliance
9  * with the License.  You may obtain a copy of the License at
10  *
11  *   http://www.apache.org/licenses/LICENSE-2.0
12  *
13  * Unless required by applicable law or agreed to in writing,
14  * software distributed under the License is distributed on an
15  * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
16  * KIND, either express or implied.  See the License for the
17  * specific language governing permissions and limitations
18  * under the License.
19  *
20  *************************************************************/
21 
22 
23 
24 #ifndef SD_SLIDESORTER_VIEW_LAYOUTER_HXX
25 #define SD_SLIDESORTER_VIEW_LAYOUTER_HXX
26 
27 #include "SlideSorter.hxx"
28 #include "view/SlsPageObjectLayouter.hxx"
29 #include "view/SlsTheme.hxx"
30 #include <sal/types.h>
31 #include <tools/fract.hxx>
32 #include <vcl/mapmod.hxx>
33 #include <vector>
34 #include <utility>
35 
36 
37 class MapMode;
38 class OutputDevice;
39 class Size;
40 
41 namespace sd { namespace slidesorter { namespace view {
42 
43 class InsertPosition;
44 
45 
46 
47 /** Calculate the size and position of page objects displayed by a slide
48     sorter.  The layouter takes into account various input values:
49     1.) Size of the window in which the slide sorter is displayed.
50     2.) Desired and minimal and maximal widths of page objects.
51     3.) Minimal and maximal number of columns.
52     4.) Vertical and horizontal gaps between objects in adjacent columns.
53     5.) Borders arround every page object.
54     6.) Vertical and horizontal borders between enclosing page and outer
55         page objects.
56     From these it calculates various output values:
57     1.) The width of page objects.
58     2.) The number of columns.
59     3.) The size of the enclosing page.
60 
61     <p>Sizes and lengths are all in pixel except where explicitly stated
62     otherwise.</p>
63 
64     <p>The GetIndex... methods may return indices that are larger than or
65     equal to (zero based) the number of pages.  This is so because the
66     number of pages is not known to the class instances.  Indices are
67     calculated with reference to the general grid layout of page
68     objects.</p>
69 */
70 class Layouter
71 {
72 public:
73     enum Orientation { HORIZONTAL, VERTICAL, GRID };
74 
75     Layouter (
76         const SharedSdWindow& rpWindow,
77         const ::boost::shared_ptr<Theme>& rpTheme);
78     ~Layouter (void);
79 
80     ::boost::shared_ptr<PageObjectLayouter> GetPageObjectLayouter (void) const;
81     /** Set the horizontal and vertical borders in pixel coordinates between
82         the enclosing window and page objects.  The borders may be painted
83         larger then the given values when the space for the insertion marker
84         is not sufficient.
85         @param nLeftBorder
86             Use a negative value to indicate that the left border size
87             shall not be modified.  A value of 10 is the default.
88         @param nRightBorder
89             Use a negative value to indicate that the right border size
90             shall not be modified.  A value of 10 is the default.
91         @param nTopBorder
92             Use a negative value to indicate that the top border size
93             shall not be modified.  A value of 10 is the default.
94         @param nBottomBorder
95             Use a negative value to indicate that the bottom border size
96             shall not be modified.  A value of 10 is the default.
97     */
98     void SetBorders (sal_Int32 nLeftBorder, sal_Int32 nRightBorder,
99         sal_Int32 nTopBorder, sal_Int32 nBottomBorder);
100 
101     /** Set the interval of valid column counts.  When nMinimalColumnCount
102         <= nMaximalColumnCount is not fullfilled then the call is ignored.
103         @param nMinimalColumnCount
104             The default value is 1.  The question whether higher values make
105             any sense is left to the caller.
106         @param nMaximalColumnCount
107             The default value is 5.
108     */
109     void SetColumnCount (sal_Int32 nMinimalColumnCount,
110         sal_Int32 nMaximalColumnCount);
111 
112     /** Central method of this class.  It takes the input values and
113         calculates the output values.  Both given sizes must not be 0 in any
114         dimension or the call is ignored.
115         @param eOrientation
116             This defines the generaly layout and specifies whether there may
117             be more than one row or more than one column.
118         @param rWindowSize
119             The size of the window in pixels that the slide sorter is
120             displayed in.  This can differ from the size of mpWindow during
121             detection of whether or not the scroll bars should be visible.
122         @param rPreviewModelSize
123             Size of each page in model coordinates.
124         @param rpWindow
125             The map mode of this window is adapted to the new layout of the
126             page objects.
127         @return
128             The return value indicates whether the Get... methods can be
129             used to obtain valid values (<TRUE/>).
130     */
131     bool Rearrange (
132         const Orientation eOrientation,
133         const Size& rWindowSize,
134         const Size& rPreviewModelSize,
135         const sal_uInt32 nPageCount);
136 
137     /** Change the zoom factor.  This does not change the general layout
138         (number of columns).
139     */
140     void _SetZoom (double nZoomFactor);
141     void _SetZoom (Fraction nZoomFactor);
142 
143     /** Return the number of columns.
144     */
145     sal_Int32 GetColumnCount (void) const;
146 
147     sal_Int32 GetRowCount (void) const;
148 
149     sal_Int32 GetRow (const sal_Int32 nIndex) const;
150 
151     sal_Int32 GetColumn (const sal_Int32 nIndex) const;
152 
153     sal_Int32 GetIndex (const sal_Int32 nRow, const sal_Int32 nColumn) const;
154 
155     /** Return the scale factor that can be set at the map mode of the
156         output window.
157     */
158     Fraction GetScaleFactor (void) const;
159 
160     Size GetPageObjectSize (void) const;
161 
162     /** Return the bounding box in window coordinates of the nIndex-th page
163         object.
164     */
165     Rectangle GetPageObjectBox (
166         const sal_Int32 nIndex,
167         const bool bIncludeBorderAndGap = false) const;
168 
169     /** Return the bounding box in model coordinates of the page that
170         contains the given amount of page objects.
171     */
172     Rectangle GetTotalBoundingBox (void) const;
173 
174     /** Return the index of the first fully or partially visible page
175         object.  This takes into account only the vertical dimension.
176         @return
177             The second index may be larger than the number of existing
178             page objects.
179     */
180     Range GetRangeOfVisiblePageObjects (const Rectangle& rVisibleArea) const;
181 
182     /** Return the index of the page object that is rendered at the given
183         point.
184         @param rPosition
185             The position is expected to be in model coordinates relative to
186             the page origin.
187         @param bIncludePageBorders
188             When <TRUE/> then include the page borders into the calculation,
189             i.e. when a point lies in the border of a page object but not on
190             the actual page area the index of that page is returned;
191             otherwise -1 would be returned to indicate that no page object
192             has been hit.
193         @param bClampToValidRange
194             When <TRUE/> then values outside the valid range [0,mnPageCount)
195             are mapped to 0 (when smaller than 0) or mnPageCount-1 when
196             equal to or larger than mnPageCount.
197             When <FALSE/> then -1 is returned for values outside the valid range.
198         @return
199             The returned index may be larger than the number of existing
200             page objects.
201     */
202     sal_Int32 GetIndexAtPoint (
203         const Point& rModelPosition,
204         const bool bIncludePageBorders = false,
205         const bool bClampToValidRange = true) const;
206 
207     /** Return an object that describes the logical and visual properties of
208         where to do an insert operation when the user would release the the
209         mouse button at the given position after a drag operation and of
210         where and how to display an insertion indicator.
211         @param rModelPosition
212             The position in the model coordinate system for which to
213             determine the insertion page index.  The position does not have
214             to be over a page object to return a valid value.
215         @param rIndicatorSize
216             The size of the insertion indicator.  This size is used to adapt
217             the location when at the left or right of a row or at the top or
218             bottom of a column.
219         @param rModel
220             The model is used to get access to the selection states of the
221             pages.  This in turn is used to determine the visual bounding
222             boxes.
223     */
224     InsertPosition GetInsertPosition (
225         const Point& rModelPosition,
226         const Size& rIndicatorSize,
227         model::SlideSorterModel& rModel) const;
228 
229     Range GetValidHorizontalSizeRange (void) const;
230     Range GetValidVerticalSizeRange (void) const;
231 
232     class Implementation;
233 
234 private:
235     ::boost::scoped_ptr<Implementation> mpImplementation;
236     SharedSdWindow mpWindow;
237 };
238 
239 
240 
241 
242 
243 /** Collect all values concerning the logical and visual properties of the
244     insertion position that is used for drag-and-drop and copy-and-past.
245 */
246 class InsertPosition
247 {
248 public:
249     InsertPosition (void);
250     InsertPosition& operator= (const InsertPosition& rInsertPosition);
251     bool operator== (const InsertPosition& rInsertPosition) const;
252     bool operator!= (const InsertPosition& rInsertPosition) const;
253 
254     void SetLogicalPosition (
255         const sal_Int32 nRow,
256         const sal_Int32 nColumn,
257         const sal_Int32 nIndex,
258         const bool bIsAtRunStart,
259         const bool bIsAtRunEnd,
260         const bool bIsExtraSpaceNeeded);
261     void SetGeometricalPosition(
262         const Point aLocation,
263         const Point aLeadingOffset,
264         const Point aTrailingOffset);
265 
GetRow(void) const266     sal_Int32 GetRow (void) const { return mnRow; }
GetColumn(void) const267     sal_Int32 GetColumn (void) const { return mnColumn; }
GetIndex(void) const268     sal_Int32 GetIndex (void) const { return mnIndex; }
GetLocation(void) const269     Point GetLocation (void) const { return maLocation; }
GetLeadingOffset(void) const270     Point GetLeadingOffset (void) const { return maLeadingOffset; }
GetTrailingOffset(void) const271     Point GetTrailingOffset (void) const { return maTrailingOffset; }
IsAtRunStart(void) const272     bool IsAtRunStart (void) const { return mbIsAtRunStart; }
IsAtRunEnd(void) const273     bool IsAtRunEnd (void) const { return mbIsAtRunEnd; }
IsExtraSpaceNeeded(void) const274     bool IsExtraSpaceNeeded (void) const { return mbIsExtraSpaceNeeded; }
275 
276 private:
277     sal_Int32 mnRow;
278     sal_Int32 mnColumn;
279     sal_Int32 mnIndex;
280     bool mbIsAtRunStart : 1;
281     bool mbIsAtRunEnd : 1;
282     bool mbIsExtraSpaceNeeded : 1;
283     Point maLocation;
284     Point maLeadingOffset;
285     Point maTrailingOffset;
286 };
287 
288 
289 
290 } } } // end of namespace ::sd::slidesorter::view
291 
292 #endif
293