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_FOCUS_MANAGER_HXX
25  #define SD_SLIDESORTER_FOCUS_MANAGER_HXX
26  
27  #include <model/SlsSharedPageDescriptor.hxx>
28  
29  #include <sal/types.h>
30  #include <tools/link.hxx>
31  #include <vector>
32  
33  namespace sd { namespace slidesorter {
34  class SlideSorter;
35  } }
36  
37  
38  namespace sd { namespace slidesorter { namespace controller {
39  
40  /** This class manages the focus of the slide sorter.  There is the focus
41      page which is or is not focused.  Initialized to point to the first page
42      it can be set to other pages by using the MoveFocus() method.  The
43      focused state of the focus page can be toggled with the ToggleFocus()
44      method.
45  */
46  class FocusManager
47  {
48  public:
49      /** Create a new focus manager that operates on the pages of the model
50          associated with the given controller.  The focus page is set to the
51          first page.  Focused state is off.
52      */
53      FocusManager (SlideSorter& rSlideSorter);
54  
55      ~FocusManager (void);
56  
57      enum FocusMoveDirection
58      {
59          FMD_NONE,
60          FMD_LEFT,
61          FMD_RIGHT,
62          FMD_UP,
63          FMD_DOWN
64      };
65  
66      /** Move the focus from the currently focused page to one that is
67          displayed adjacent to it, either vertically or horizontally.
68          @param eDirection
69              Direction in which to move the focus.  Wrap around is done
70              differently when moving vertically or horizontally.  Vertical
71              wrap around takes place in the same column, i.e. when you are
72              in the top row and move up you come out in the bottom row in the
73              same column.  Horizontal wrap around moves to the next
74              (FMD_RIGHT) or previous (FMD_LEFT) page.  Moving to the right
75              from the last page goes to the first page and vice versa.
76              When FMD_NONE is given, the current page index is checked for
77              being valid.  If it is not, then it is set to the nearest valid
78              page index.
79      */
80      void MoveFocus (FocusMoveDirection eDirection);
81  
82      /** Show the focus indicator of the current slide.
83          @param bScrollToFocus
84              When <TRUE/> (the default) then the view is scrolled so that the
85              focus rectangle lies inside its visible area.
86      */
87      void ShowFocus (const bool bScrollToFocus = true);
88  
89      /** Hide the focus indicator.
90      */
91      void HideFocus (void);
92  
93      /** Toggle the focused state of the current slide.
94          @return
95              Returns the focused state of the focus page after the call.
96      */
97      bool ToggleFocus (void);
98  
99      /** Return whether the window managed by the called focus manager has
100          the input focus of the application.
101      */
102      bool HasFocus (void) const;
103  
104      /** Return the descriptor of the page that currently has the focus.
105          @return
106              When there is no page that currently has the focus then NULL is
107              returned.
108      */
109      model::SharedPageDescriptor GetFocusedPageDescriptor (void) const;
110  
111      /** Return the index of the page that currently has the focus as it is
112          accepted by the slide sorter model.
113          @return
114              When there is no page that currently has the focus then -1 is
115              returned.
116      */
117      sal_Int32 GetFocusedPageIndex (void) const;
118  
119      /** Set the focused page to the one described by the given page
120          descriptor.  The visibility of the focus indicator is not modified.
121          @param rDescriptor
122              One of the page descriptors that are currently managed by the
123              SlideSorterModel.
124      */
125      void SetFocusedPage (const model::SharedPageDescriptor& rDescriptor);
126  
127      /** Set the focused page to the one described by the given page
128          index.  The visibility of the focus indicator is not modified.
129          @param nPageIndex
130              A valid page index that is understood by the SlideSorterModel.
131      */
132      void SetFocusedPage (sal_Int32 nPageIndex);
133  
134      void SetFocusedPageToCurrentPage (void);
135  
136      /** Return <TRUE/> when the focus indicator is currently shown.  A
137          prerequisite is that the window managed by this focus manager has
138          the input focus as indicated by a <TRUE/> return value of
139          HasFocus().  It is not necessary that the focus indicator is
140          visible.  It may have been scrolled outside the visible area.
141      */
142      bool IsFocusShowing (void) const;
143  
144      /** Add a listener that is called when the focus is shown or hidden or
145          set to another page object.
146          @param rListener
147              When this method is called multiple times for the same listener
148              the second and all following calls are ignored.  Each listener
149              is added only once.
150      */
151      void AddFocusChangeListener (const Link& rListener);
152  
153      /** Remove a focus change listener.
154          @param rListener
155              It is save to pass a listener that was not added are has been
156              removed previously.  Such calls are ignored.
157      */
158      void RemoveFocusChangeListener (const Link& rListener);
159  
160      /** Move focus to sibling outside the actual slide sorter.  This is
161          typically the tool bar with the close button.
162      */
163      void SetFocusToToolBox (void);
164  
165      /** Create an instance of this class to temporarily hide the focus
166          indicator.  It is restored to its former visibility state when the
167          FocusHider is destroyed.
168      */
169      class FocusHider
170      {
171      public:
172          FocusHider (FocusManager&);
173          ~FocusHider (void);
174      private:
175          bool mbFocusVisible;
176          FocusManager& mrManager;
177      };
178  
179  private:
180      SlideSorter& mrSlideSorter;
181  
182      /** Index of the page that may be focused.  It is -1 when the model
183          contains no page.
184      */
185      sal_Int32 mnPageIndex;
186  
187      /** This flag indicates whether the page pointed to by mpFocusDescriptor
188          has the focus.
189      */
190      bool mbPageIsFocused;
191  
192      ::std::vector<Link> maFocusChangeListeners;
193  
194      /** When vertical wrap is active then pressing UP in the top row moves
195          the focus to the bottom row, DOWN in the bottom row moves the focus
196          to the top row.
197      */
198      bool mbIsVerticalWrapActive;
199  
200      /** Reset the focus state of the given descriptor and request a repaint
201          so that the focus indicator is hidden.
202          @param pDescriptor
203              When NULL is given then the call is ignored.
204      */
205      void HideFocusIndicator (const model::SharedPageDescriptor& rpDescriptor);
206  
207      /** Set the focus state of the given descriptor, scroll it into the
208          visible area and request a repaint so that the focus indicator is
209          made visible.
210          @param pDescriptor
211              When NULL is given then the call is ignored.
212          @param bScrollToFocus
213              When <TRUE/> (the default) then the view is scrolled so that the
214              focus rectangle lies inside its visible area.
215      */
216      void ShowFocusIndicator (
217          const model::SharedPageDescriptor& rpDescriptor,
218          const bool bScrollToFocus);
219  
220      /** Call all currently registered listeners that a focus change has
221          happened.  The focus may be hidden or shown or moved from one page
222          object to another.
223      */
224      void NotifyFocusChangeListeners (void) const;
225  };
226  
227  } } } // end of namespace ::sd::slidesorter::controller
228  
229  #endif
230