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_SLIDE_SORTER_SCROLL_BAR_MANAGER_HXX
25 #define SD_SLIDESORTER_SLIDE_SORTER_SCROLL_BAR_MANAGER_HXX
26 
27 #include "SlideSorter.hxx"
28 
29 #include <tools/link.hxx>
30 #include <tools/gen.hxx>
31 #include <vcl/timer.hxx>
32 #include <boost/shared_ptr.hpp>
33 #include <boost/function.hpp>
34 
35 class Point;
36 class Rectangle;
37 class ScrollBar;
38 class ScrollBarBox;
39 class Window;
40 
41 namespace sd {
42 class Window;
43 }
44 
45 namespace sd { namespace slidesorter {
46     class SlideSorter;
47 } }
48 
49 
50 namespace sd { namespace slidesorter { namespace controller {
51 
52 /** Manage the horizontal and vertical scroll bars.  Listen for events, set
53     their sizes, place them in the window, determine their visibilities.
54 
55     <p>Handle auto scrolling, i.e. the scrolling of the window when the
56     mouse comes near the window border while dragging a selection.</p>
57 
58     <p>In order to make the slide sorter be used in the task pane with its
59     own vertical scrollbars the vertical scrollbar of the use of the slide
60     sorter is optional.  When using it the available area in a window is
61     used and the vertical scrollbar is displayed when that area is not large
62     enough.  When the vertical scrollbar is not used then the available area
63     is assumed to be modifiable.  In that case the PlaceScrollBars() method
64     may return an area larger than the one given.<p>
65 */
66 class ScrollBarManager
67 {
68 public:
69     /** Create a new scroll bar manager that manages three controls: the
70         horizontal scroll bar, the vertical scroll bar, and the little
71         window that fills the gap at the bottom right corner that is left
72         between the two scroll bars.  Call LateInitialization() after
73         constructing a new object.
74     */
75     ScrollBarManager (SlideSorter& rSlideSorter);
76 
77     ~ScrollBarManager (void);
78 
79     /** Call this method after constructing a new object of this class.
80     */
81     void LateInitialization (void);
82 
83     /** Register listeners at the scroll bars.  This method is called after
84         startup of a new slide sorter object or after a reactivation of a
85         slide sorter that for example is taken from a cache.
86     */
87     void Connect (void);
88 
89     /** Remove listeners from the scroll bars.  This method is called whent
90         the slide sorter is destroyed or when it is suspended, e.g. put
91         into a cache for later reuse.
92     */
93     void Disconnect (void);
94 
95     /** Set up the scroll bar, i.e. thumb size and position.  Call this
96         method when the content of the browser window changed, i.e. pages
97         were inserted or deleted, the layout or the zoom factor has
98         changed.
99         @param bResetThumbPosition
100             When <TRUE/> then set the thumb position to position 0.  This is
101             done when e.g. switching between master page mode and draw mode.
102         @param bScrollToCurrentPosition
103             When <TRUE/> then scroll the window to the new offset that is
104             defined by the scroll bars.  Otherwise the new offset is simply
105             set and the whole window is repainted.
106     */
107     void UpdateScrollBars (
108         bool bResetThumbPosition = false,
109         bool bScrollToCurrentPosition = true);
110 
111     /** Place the scroll bars inside the given area.  When the available
112         area is not large enough for the content to display the horizontal
113         and/or vertical scroll bar is enabled.
114         @param rAvailableArea
115             The scroll bars will be placed inside this rectangle.  It is
116             expected to be given in pixel relative to its parent.
117         @param bIsHorizontalScrollBarAllowed
118             Only when this flag is <TRUE/> the horizontal scroll may be
119             displayed.
120         @param bIsVerticalScrollBarAllowed
121             Only when this flag is <TRUE/> the horizontal scroll may be
122             displayed.
123         @return
124             Returns the space that remains after the scroll bars are
125             placed.
126     */
127     Rectangle PlaceScrollBars (
128         const Rectangle& rAvailableArea,
129         const bool bIsHorizontalScrollBarAllowed,
130         const bool bIsVerticalScrollBarAllowed);
131 
132     /** Update the vertical and horizontal scroll bars so that the visible
133         area has the given top and left values.
134     */
135     void SetTopLeft (const Point aNewTopLeft);
136 
137     sal_Int32 GetTop (void) const;
138 
139     sal_Int32 GetLeft (void) const;
140 
141     /** Return the width of the vertical scroll bar, which--when
142         shown--should be fixed in contrast to its height.
143         @return
144            Returns 0 when the vertical scroll bar is not shown or does not
145            exist, otherwise its width in pixel is returned.
146     */
147     int GetVerticalScrollBarWidth (void) const;
148 
149     /** Return the height of the horizontal scroll bar, which--when
150         shown--should be fixed in contrast to its width.
151         @return
152            Returns 0 when the vertical scroll bar is not shown or does not
153            exist, otherwise its height in pixel is returned.
154     */
155     int GetHorizontalScrollBarHeight (void) const;
156 
157     /** Call this method to scroll a window while the mouse is in dragging a
158         selection.  If the mouse is near the window border or is outside the
159         window then scroll the window accordingly.
160         @param rMouseWindowPosition
161             The mouse position for which the scroll amount is calculated.
162         @param rAutoScrollFunctor
163             Every time when the window is scrolled then this functor is executed.
164         @return
165             When the window is scrolled then this method returns <TRUE/>.
166             When the window is not changed then <FALSE/> is returned.
167     */
168     bool AutoScroll (
169         const Point& rMouseWindowPosition,
170         const ::boost::function<void(void)>& rAutoScrollFunctor);
171 
172     void StopAutoScroll (void);
173 
174     enum Orientation { Orientation_Horizontal, Orientation_Vertical };
175     enum Unit { Unit_Pixel, Unit_Slide };
176     /** Scroll the slide sorter by setting the thumbs of the scroll bars and
177         by moving the content of the content window.
178         @param eOrientation
179             Defines whether to scroll horizontally or vertically.
180         @param eUnit
181             Defines whether the distance is a pixel value or the number of
182             slides to scroll.
183     */
184     void Scroll(
185         const Orientation eOrientation,
186         const Unit eUnit,
187         const sal_Int32 nDistance);
188 
189 private:
190     SlideSorter& mrSlideSorter;
191 
192     /** The horizontal scroll bar.  Note that is used but not owned by
193         objects of this class.  It is given to the constructor.
194     */
195     ::boost::shared_ptr<ScrollBar> mpHorizontalScrollBar;
196 
197     /** The vertical scroll bar.  Note that is used but not owned by
198         objects of this class.  It is given to the constructor.
199     */
200     ::boost::shared_ptr<ScrollBar> mpVerticalScrollBar;
201 
202     /// Relative horizontal position of the visible area in the view.
203     double mnHorizontalPosition;
204     /// Relative vertical position of the visible area in the view.
205     double mnVerticalPosition;
206     /** The width and height of the border at the inside of the window which
207         when entered while in drag mode leads to a scrolling of the window.
208     */
209     Size maScrollBorder;
210     double mnHorizontalScrollFactor;
211     double mnVerticalScrollFactor;
212     /** The only task of this little window is to paint the little square at
213         the bottom right corner left by the two scroll bars (when both are
214         visible).
215     */
216     ::boost::shared_ptr<ScrollBarBox> mpScrollBarFiller;
217 
218     /** The auto scroll timer is used for keep scrolling the window when the
219         mouse reaches its border while dragging a selection.  When the mouse
220         is not moved the timer issues events to keep scrolling.
221     */
222     Timer maAutoScrollTimer;
223     Size maAutoScrollOffset;
224     bool mbIsAutoScrollActive;
225 
226     /** The content window is the one whose view port is controlled by the
227         scroll bars.
228     */
229     SharedSdWindow mpContentWindow;
230 
231     ::boost::function<void(void)> maAutoScrollFunctor;
232 
233     void SetWindowOrigin (
234         double nHorizontalPosition,
235         double nVerticalPosition);
236 
237     /** Determine the visibility of the scroll bars so that the window
238         content is not clipped in any dimension without showing a scroll
239         bar.
240         @param rAvailableArea
241             The area in which the scroll bars, the scroll bar filler, and
242             the SlideSorterView will be placed.
243         @return
244             The area that is enclosed by the scroll bars is returned.  It
245             will be filled with the SlideSorterView.
246     */
247     Rectangle DetermineScrollBarVisibilities(
248         const Rectangle& rAvailableArea,
249         const bool bIsHorizontalScrollBarAllowed,
250         const bool bIsVerticalScrollBarAllowed);
251 
252     /** Typically called by DetermineScrollBarVisibilities() this method
253         tests a specific configuration of the two scroll bars being visible
254         or hidden.
255         @return
256             When the window content can be shown with only being clipped in
257             an orientation where the scroll bar would be shown then <TRUE/>
258             is returned.
259     */
260     bool TestScrollBarVisibilities (
261         bool bHorizontalScrollBarVisible,
262         bool bVerticalScrollBarVisible,
263         const Rectangle& rAvailableArea);
264 
265     void CalcAutoScrollOffset (const Point& rMouseWindowPosition);
266     bool RepeatAutoScroll (void);
267 
268 	DECL_LINK(HorizontalScrollBarHandler, ScrollBar*);
269 	DECL_LINK(VerticalScrollBarHandler, ScrollBar*);
270 	DECL_LINK(AutoScrollTimeoutHandler, Timer*);
271 
272     void PlaceHorizontalScrollBar (const Rectangle& aArea);
273     void PlaceVerticalScrollBar (const Rectangle& aArea);
274     void PlaceFiller (const Rectangle& aArea);
275 };
276 
277 } } } // end of namespace ::sd::slidesorter::controller
278 
279 #endif
280