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