xref: /AOO41X/main/sd/source/ui/slidesorter/controller/SlsFocusManager.cxx (revision 124601a829d5e9b9811fc2a410769f24f6ca3495)
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 #include "precompiled_sd.hxx"
25 #include "controller/SlsFocusManager.hxx"
26 
27 #include "SlideSorter.hxx"
28 #include "PaneDockingWindow.hxx"
29 #include "controller/SlideSorterController.hxx"
30 #include "controller/SlsCurrentSlideManager.hxx"
31 #include "controller/SlsVisibleAreaManager.hxx"
32 #include "model/SlideSorterModel.hxx"
33 #include "model/SlsPageDescriptor.hxx"
34 #include "view/SlideSorterView.hxx"
35 #include "view/SlsLayouter.hxx"
36 #include <vcl/toolbox.hxx>
37 
38 #include "Window.hxx"
39 #include "sdpage.hxx"
40 
41 #define UNIFY_FOCUS_AND_CURRENT_PAGE
42 
43 namespace sd { namespace slidesorter { namespace controller {
44 
45 FocusManager::FocusManager (SlideSorter& rSlideSorter)
46     : mrSlideSorter(rSlideSorter),
47       mnPageIndex(0),
48       mbPageIsFocused(false),
49       mbIsVerticalWrapActive(false)
50 {
51     if (mrSlideSorter.GetModel().GetPageCount() > 0)
52         mnPageIndex = 0;
53 }
54 
55 
56 
57 
58 FocusManager::~FocusManager (void)
59 {
60 }
61 
62 
63 
64 
65 void FocusManager::MoveFocus (FocusMoveDirection eDirection)
66 {
67     if (mnPageIndex >= 0 && mbPageIsFocused)
68     {
69         HideFocusIndicator (GetFocusedPageDescriptor());
70 
71         const sal_Int32 nColumnCount (mrSlideSorter.GetView().GetLayouter().GetColumnCount());
72         const sal_Int32 nPageCount (mrSlideSorter.GetModel().GetPageCount());
73         switch (eDirection)
74         {
75             case FMD_NONE:
76                 // Nothing to be done.
77                 break;
78 
79             case FMD_LEFT:
80                 if (mnPageIndex > 0)
81                     mnPageIndex -= 1;
82                 else if (mbIsVerticalWrapActive)
83                     mnPageIndex = nPageCount-1;
84                 break;
85 
86             case FMD_RIGHT:
87                 if (mnPageIndex < nPageCount-1)
88                     mnPageIndex += 1;
89                 else if (mbIsVerticalWrapActive)
90                     mnPageIndex = 0;
91                 break;
92 
93             case FMD_UP:
94             {
95                 const sal_Int32 nCandidate (mnPageIndex - nColumnCount);
96                 if (nCandidate < 0)
97                 {
98                     if (mbIsVerticalWrapActive)
99                     {
100                         // Wrap arround to the bottom row or the one above
101                         // and go to the correct column.
102                         const sal_Int32 nLastIndex (nPageCount-1);
103                         const sal_Int32 nLastColumn (nLastIndex % nColumnCount);
104                         const sal_Int32 nCurrentColumn (mnPageIndex%nColumnCount);
105                         if (nLastColumn >= nCurrentColumn)
106                         {
107                             // The last row contains the current column.
108                             mnPageIndex = nLastIndex - (nLastColumn-nCurrentColumn);
109                         }
110                         else
111                         {
112                             // Only the second to last row contains the current column.
113                             mnPageIndex = nLastIndex - nLastColumn
114                                 - nColumnCount
115                                 + nCurrentColumn;
116                         }
117                     }
118                 }
119                 else
120                 {
121                     // Move the focus the previous row.
122                     mnPageIndex = nCandidate;
123                 }
124             }
125             break;
126 
127             case FMD_DOWN:
128             {
129                 const sal_Int32 nCandidate (mnPageIndex + nColumnCount);
130                 if (nCandidate >= nPageCount)
131                 {
132                     if (mbIsVerticalWrapActive)
133                     {
134                         // Wrap arround to the correct column.
135                         mnPageIndex = mnPageIndex % nColumnCount;
136                     }
137                     else
138                     {
139                         // Do not move the focus.
140                     }
141                 }
142                 else
143                 {
144                     // Move the focus to the next row.
145                     mnPageIndex = nCandidate;
146                 }
147             }
148             break;
149         }
150 
151         if (mnPageIndex < 0)
152         {
153             OSL_ASSERT(mnPageIndex>=0);
154             mnPageIndex = 0;
155         }
156         else if (mnPageIndex >= nPageCount)
157         {
158             OSL_ASSERT(mnPageIndex<nPageCount);
159             mnPageIndex = nPageCount - 1;
160         }
161 
162         if (mbPageIsFocused)
163         {
164             ShowFocusIndicator(GetFocusedPageDescriptor(), true);
165         }
166     }
167 }
168 
169 
170 
171 
172 void FocusManager::ShowFocus (const bool bScrollToFocus)
173 {
174     mbPageIsFocused = true;
175     ShowFocusIndicator(GetFocusedPageDescriptor(), bScrollToFocus);
176 }
177 
178 
179 
180 
181 void FocusManager::HideFocus (void)
182 {
183     mbPageIsFocused = false;
184     HideFocusIndicator(GetFocusedPageDescriptor());
185 }
186 
187 
188 
189 
190 bool FocusManager::ToggleFocus (void)
191 {
192     if (mnPageIndex >= 0)
193     {
194         if (mbPageIsFocused)
195             HideFocus ();
196         else
197             ShowFocus ();
198     }
199     return mbPageIsFocused;
200 }
201 
202 
203 
204 
205 bool FocusManager::HasFocus (void) const
206 {
207     return mrSlideSorter.GetContentWindow()->HasFocus();
208 }
209 
210 
211 
212 
213 model::SharedPageDescriptor FocusManager::GetFocusedPageDescriptor (void) const
214 {
215     return mrSlideSorter.GetModel().GetPageDescriptor(mnPageIndex);
216 }
217 
218 
219 
220 
221 sal_Int32 FocusManager::GetFocusedPageIndex (void) const
222 {
223     return mnPageIndex;
224 }
225 
226 
227 
228 /*
229 void FocusManager::FocusPage (sal_Int32 nPageIndex)
230 {
231     if (nPageIndex != mnPageIndex)
232     {
233         // Hide the focus while switching it to the specified page.
234         FocusHider aHider (*this);
235         mnPageIndex = nPageIndex;
236     }
237 
238     if (HasFocus() && !IsFocusShowing())
239         ShowFocus();
240 }
241 */
242 
243 
244 
245 void FocusManager::SetFocusedPage (const model::SharedPageDescriptor& rpDescriptor)
246 {
247     if (rpDescriptor.get() != NULL)
248     {
249         FocusHider aFocusHider (*this);
250         mnPageIndex = (rpDescriptor->GetPage()->GetPageNum()-1)/2;
251     }
252 }
253 
254 
255 
256 
257 void FocusManager::SetFocusedPage (sal_Int32 nPageIndex)
258 {
259     FocusHider aFocusHider (*this);
260     mnPageIndex = nPageIndex;
261 }
262 
263 
264 
265 
266 void FocusManager::SetFocusedPageToCurrentPage (void)
267 {
268     SetFocusedPage(mrSlideSorter.GetController().GetCurrentSlideManager()->GetCurrentSlide());
269 }
270 
271 
272 
273 
274 bool FocusManager::IsFocusShowing (void) const
275 {
276     return HasFocus() && mbPageIsFocused;
277 }
278 
279 
280 
281 
282 void FocusManager::HideFocusIndicator (const model::SharedPageDescriptor& rpDescriptor)
283 {
284 	if (rpDescriptor.get() != NULL)
285 	{
286         mrSlideSorter.GetView().SetState(rpDescriptor, model::PageDescriptor::ST_Focused, false);
287 	}
288 }
289 
290 
291 
292 
293 void FocusManager::ShowFocusIndicator (
294     const model::SharedPageDescriptor& rpDescriptor,
295     const bool bScrollToFocus)
296 {
297     if (rpDescriptor.get() != NULL)
298     {
299         mrSlideSorter.GetView().SetState(rpDescriptor, model::PageDescriptor::ST_Focused, true);
300 
301         if (bScrollToFocus)
302         {
303             // Scroll the focused page object into the visible area and repaint
304             // it, so that the focus indicator becomes visible.
305             mrSlideSorter.GetController().GetVisibleAreaManager().RequestVisible(rpDescriptor,true);
306         }
307         mrSlideSorter.GetView().RequestRepaint(rpDescriptor);
308 
309         NotifyFocusChangeListeners();
310     }
311 }
312 
313 
314 
315 
316 void FocusManager::AddFocusChangeListener (const Link& rListener)
317 {
318     if (::std::find (maFocusChangeListeners.begin(), maFocusChangeListeners.end(), rListener)
319         == maFocusChangeListeners.end())
320     {
321         maFocusChangeListeners.push_back (rListener);
322     }
323 }
324 
325 
326 
327 
328 void FocusManager::RemoveFocusChangeListener (const Link& rListener)
329 {
330     maFocusChangeListeners.erase (
331         ::std::find (maFocusChangeListeners.begin(), maFocusChangeListeners.end(), rListener));
332 }
333 
334 
335 
336 
337 void FocusManager::SetFocusToToolBox (void)
338 {
339     HideFocus();
340 
341     if (mrSlideSorter.GetViewShell() != NULL)
342     {
343         ::Window* pParentWindow = mrSlideSorter.GetViewShell()->GetParentWindow();
344         DockingWindow* pDockingWindow = NULL;
345         while (pParentWindow!=NULL && pDockingWindow==NULL)
346         {
347             pDockingWindow = dynamic_cast<DockingWindow*>(pParentWindow);
348             pParentWindow = pParentWindow->GetParent();
349         }
350         if (pDockingWindow)
351         {
352             PaneDockingWindow* pPaneDockingWindow = dynamic_cast<PaneDockingWindow*>(pDockingWindow);
353             if (pPaneDockingWindow != NULL)
354                 pPaneDockingWindow->GetToolBox().GrabFocus();
355         }
356     }
357 }
358 
359 
360 
361 
362 void FocusManager::NotifyFocusChangeListeners (void) const
363 {
364     // Create a copy of the listener list to be safe when that is modified.
365     ::std::vector<Link> aListeners (maFocusChangeListeners);
366 
367     // Tell the slection change listeners that the selection has changed.
368     ::std::vector<Link>::iterator iListener (aListeners.begin());
369     ::std::vector<Link>::iterator iEnd (aListeners.end());
370     for (; iListener!=iEnd; ++iListener)
371     {
372         iListener->Call(NULL);
373     }
374 }
375 
376 
377 
378 
379 FocusManager::FocusHider::FocusHider (FocusManager& rManager)
380 : mbFocusVisible(rManager.IsFocusShowing())
381 , mrManager(rManager)
382 {
383     mrManager.HideFocus();
384 }
385 
386 
387 
388 
389 FocusManager::FocusHider::~FocusHider (void)
390 {
391     if (mbFocusVisible)
392         mrManager.ShowFocus();
393 }
394 
395 } } } // end of namespace ::sd::slidesorter::controller
396 
397