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_BUTTON_BAR_HXX
25 #define SD_SLIDESORTER_VIEW_BUTTON_BAR_HXX
26 
27 #include "model/SlsSharedPageDescriptor.hxx"
28 #include <tools/gen.hxx>
29 #include <rtl/ustring.hxx>
30 #include <vcl/bitmapex.hxx>
31 #include <vcl/bmpacc.hxx>
32 #include <boost/scoped_ptr.hpp>
33 
34 namespace sd { namespace slidesorter {
35 class SlideSorter;
36 } }
37 
38 
39 namespace sd { namespace slidesorter { namespace view {
40 
41 class Theme;
42 
43 class Button;
44 typedef ::boost::shared_ptr<Button> SharedButton;
45 
46 /** This is a container of buttons and a coordinating controller.
47     The last means that it receives mouse events and forwards them to
48     the right button.
49 */
50 class ButtonBar
51 {
52 public:
53     ButtonBar (SlideSorter& rSlideSorter);
54     ~ButtonBar (void);
55 
56     void ProcessButtonDownEvent (
57         const model::SharedPageDescriptor& rpDescriptor,
58         const Point aMouseModelLocation);
59     void ProcessButtonUpEvent (
60         const model::SharedPageDescriptor& rpDescriptor,
61         const Point aMouseModelLocation);
62     void ProcessMouseMotionEvent (
63         const model::SharedPageDescriptor& rpDescriptor,
64         const Point aMouseModelLocation,
65         const bool bIsMouseButtonDown);
66 
67     void ResetPage (void);
68 
69     /** Return the number of buttons that are to be displayed in page
70         objects which the mouse hovers over.
71         @param bIsExcluded
72             When this flag is <TRUE/> then return the number of
73             buttons that is to be displayed for pages that are
74             excluded from the slide show.
75     */
76     sal_Int32 GetButtonCount (const bool bIsExcluded) const;
77 
78     /** Return the specified button.
79         @param nIndex
80             Valid values lie in the range [0,GetButtonCount()).
81         @param bIsExcluded
82             When this flag is <TRUE/> then return a button that is to
83             be displayed for pages that are excluded from the slide
84             show.
85         @return
86             Returns an empty pointer when the given index is not valid.
87     */
88     ::boost::shared_ptr<Button> GetButton (
89         const bool bIsExcluded,
90         const sal_Int32 nIndex) const;
91 
92     bool IsMouseOverBar (void) const;
93 
94     /** Paint the specified page object.  When this is not the same as the
95         one under the mouse (mpDescriptor) then the buttons are all
96         painted in their normal state.
97     */
98     void Paint (
99         OutputDevice& rDevice,
100         const model::SharedPageDescriptor& rpPageDescriptor);
101 
102     bool IsMouseOverButton (void) const;
103 
104     void RequestLayout (void);
105 
106     /** Return the help text for the button under the mouse.
107         @return
108             When the mouse is not over a button then an empty string
109             is returned.
110     */
111     ::rtl::OUString GetButtonHelpText (void) const;
112 
113     /** Request the button bar to be shown.
114         @param bAnimate
115             This flag controls whether to just show the button bar (<FALSE/>)
116             or to fade it in smoothly (<TRUE/>.)
117     */
118     void RequestFadeIn (
119         const model::SharedPageDescriptor& rpDescriptor,
120         const bool bAnimate);
121 
122     /** Request the button bar to be hidden.
123         @param bAnimate
124             This flag controls whether to just hide the button bar (<FALSE/>)
125             or to fade it out smoothly (<TRUE/>.)
126     */
127     void RequestFadeOut (
128         const model::SharedPageDescriptor& rpDescriptor,
129         const bool bAnimate);
130 
131     /** Return whether the button bar is visible for the givn descriptor (or
132         being faded in.)
133     */
134     bool IsVisible (const model::SharedPageDescriptor& rpDescriptor);
135 
136     void HandleDataChangeEvent (void);
137 
138     class BackgroundTheme;
139 
140     /** While at least one Lock object exists the button bar will not be
141         displayed.  Used, e.g. during a mouse multiselection to avoid
142         confusing and unhelpfull visual signals.
143     */
144     class Lock
145     {
146     public:
147         Lock (SlideSorter& rSlideSorter);
148         ~Lock (void);
149     private:
150         ButtonBar& mrButtonBar;
151     };
152 
153 private:
154     SlideSorter& mrSlideSorter;
155     Size maPageObjectSize;
156     Rectangle maButtonBoundingBox;
157     Point maBackgroundLocation;
158     model::SharedPageDescriptor mpDescriptor;
159     bool mbIsExcluded;
160     boost::shared_ptr<Button> mpButtonUnderMouse;
161     // The button on which the mouse button was pressed.
162     boost::shared_ptr<Button> mpDownButton;
163     ::std::vector<SharedButton> maRegularButtons;
164     ::std::vector<SharedButton> maExcludedButtons;
165     BitmapEx maNormalBackground;
166     BitmapEx maButtonDownBackground;
167     bool mbIsMouseOverBar;
168     ::boost::scoped_ptr<BackgroundTheme> mpBackgroundTheme;
169     int mnLockCount;
170 
171     /** Remember the specified page.  If it differs from mpDescriptor then
172         the buttons are placed anew.
173         @return
174             The returned flag indicates wether the mpDescriptor member
175             is set to a new value.
176     */
177     bool SetPage (const model::SharedPageDescriptor& rpDescriptor);
178     SharedButton GetButtonAt (const Point aModelLocation);
179     bool SetButtonUnderMouse (const SharedButton& rButton = SharedButton());
180     void PaintButtonBackground (
181         OutputDevice& rDevice,
182         const model::SharedPageDescriptor& rpPageDescriptor,
183         const Point aOffset);
184     void LayoutButtons (const Size aPageModelSize);
185     bool LayoutButtons (void);
186     BitmapEx CreateBackground (
187         const OutputDevice& rTemplateDevice,
188         const bool bIsButtonDown) const;
189     bool IsMouseOverBar (const Point aModelLocation) const;
190     void StartFadeAnimation (
191         const model::SharedPageDescriptor& rpDescriptor,
192         const double nTargetAlpha,
193         const bool bFadeIn);
194 
195     void AcquireLock (void);
196     void ReleaseLock (void);
197 };
198 
199 
200 
201 
202 class Button
203 {
204 public:
205     Button (
206         SlideSorter& rSlideSorter,
207         const ::rtl::OUString& rsHelpText);
208     virtual ~Button (void);
209 
210     enum State { State_Normal, State_Hover, State_Down };
211     enum IconSize { IconSize_Large, IconSize_Medium, IconSize_Small };
212 
213     /** Set a new state.
214         @return
215             When the new state is different from the old state
216             then <TRUE/> is returned.
217     */
218     bool SetState (const State eState);
219     State GetState (void) const;
220 
221     virtual void Place (const Rectangle aButtonBarBox) = 0;
222     virtual void Paint (
223         OutputDevice& rDevice,
224         const Point aOffset,
225         const double nAlpha,
226         const ::boost::shared_ptr<Theme>& rpTheme) const = 0;
227     virtual void ProcessClick (const model::SharedPageDescriptor& rpDescriptor) = 0;
228 
229     /** Return the bounding box of the layouted button.
230     */
231     Rectangle GetBoundingBox (void) const;
232     /** Return the minimum size required to completely paint the
233         button.
234     */
235     virtual Size GetSize (void) const = 0;
236     virtual Size GetSize (const IconSize eIconSize) const = 0;
237     ::rtl::OUString GetHelpText (void) const;
238     bool IsDown (void) const;
239     void SetActiveState (const bool bIsActive);
240     bool IsActive (void) const;
241     void SetIconSize (const IconSize eIconSize);
242     IconSize GetIconSize (void) const;
243     /** By default a button is always enabled.  Override to change this.
244     */
245     virtual bool IsEnabled (void) const;
246 
247 protected:
248     SlideSorter& mrSlideSorter;
249     State meState;
250     Rectangle maBoundingBox;
251     const ::rtl::OUString msHelpText;
252     // Buttons that lie (partly) outside the button bar are deactivated.
253     bool mbIsActive;
254     IconSize meIconSize;
255 };
256 
257 
258 
259 class TextButton : public Button
260 {
261 public:
262     TextButton (
263         SlideSorter& rSlideSorter,
264         const ::rtl::OUString& rsText,
265         const ::rtl::OUString& rsHelpText);
266 
267     virtual void Place (const Rectangle aButtonBarBox);
268     virtual void Paint (
269         OutputDevice& rDevice,
270         const Point aOffset,
271         const double nAlpha,
272         const ::boost::shared_ptr<Theme>& rpTheme) const;
273     virtual Size GetSize (void) const;
274     virtual Size GetSize (const IconSize eIconSize) const;
275 
276 private:
277     const ::rtl::OUString msText;
278 };
279 
280 
281 
282 class ImageButton : public Button
283 {
284 public:
285     ImageButton (
286         SlideSorter& rSlideSorter,
287         const BitmapEx& rLargeIcon,
288         const BitmapEx& rLargeHoverIcon,
289         const BitmapEx& rMediumIcon,
290         const BitmapEx& rMediumHoverIcon,
291         const BitmapEx& rSmallIcon,
292         const BitmapEx& rSmallHoverIcon,
293         const ::rtl::OUString& rsHelpText);
294 
295     virtual void Place (const Rectangle aButtonBarBox);
296     virtual void Paint (
297         OutputDevice& rDevice,
298         const Point aOffset,
299         const double nAlpha,
300         const ::boost::shared_ptr<Theme>& rpTheme) const;
301     virtual Size GetSize (void) const;
302     virtual Size GetSize (const IconSize eIconSize) const;
303 
304 private:
305     const BitmapEx maLargeIcon;
306     const BitmapEx maLargeHoverIcon;
307     const BitmapEx maMediumIcon;
308     const BitmapEx maMediumHoverIcon;
309     const BitmapEx maSmallIcon;
310     const BitmapEx maSmallHoverIcon;
311 };
312 
313 
314 class UnhideButton : public ImageButton
315 {
316 public:
317     UnhideButton (SlideSorter& rSlideSorter);
318 
319 protected:
320     virtual void ProcessClick (const model::SharedPageDescriptor& rpDescriptor);
321 };
322 
323 
324 class StartShowButton : public ImageButton
325 {
326 public:
327     StartShowButton (SlideSorter& rSlideSorter);
328     virtual bool IsEnabled (void) const;
329 
330 protected:
331     virtual void ProcessClick (const model::SharedPageDescriptor& rpDescriptor);
332 };
333 
334 
335 class HideButton : public ImageButton
336 {
337 public:
338     HideButton (SlideSorter& rSlideSorter);
339 
340 protected:
341     virtual void ProcessClick (const model::SharedPageDescriptor& rpDescriptor);
342 };
343 
344 
345 class DuplicateButton : public ImageButton
346 {
347 public:
348     DuplicateButton (SlideSorter& rSlideSorter);
349     virtual bool IsEnabled (void) const;
350 
351 protected:
352     virtual void ProcessClick (const model::SharedPageDescriptor& rpDescriptor);
353 };
354 
355 
356 } } } // end of namespace ::sd::slidesorter::view
357 
358 #endif
359