bump product version to 5.0.4.1
[LibreOffice.git] / sd / source / ui / slidesorter / controller / SlsFocusManager.cxx
blobaff6a5e1727cc77b072ac733e72fad2492ea6f52
1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 /*
3 * This file is part of the LibreOffice project.
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/.
9 * This file incorporates work covered by the following license notice:
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 .
20 #include "controller/SlsFocusManager.hxx"
22 #include "SlideSorter.hxx"
23 #include "PaneDockingWindow.hxx"
24 #include "controller/SlideSorterController.hxx"
25 #include "controller/SlsCurrentSlideManager.hxx"
26 #include "controller/SlsVisibleAreaManager.hxx"
27 #include "model/SlideSorterModel.hxx"
28 #include "model/SlsPageDescriptor.hxx"
29 #include "view/SlideSorterView.hxx"
30 #include "view/SlsLayouter.hxx"
31 #include <vcl/toolbox.hxx>
33 #include "Window.hxx"
34 #include "sdpage.hxx"
36 namespace sd { namespace slidesorter { namespace controller {
38 FocusManager::FocusManager (SlideSorter& rSlideSorter)
39 : mrSlideSorter(rSlideSorter),
40 mnPageIndex(0),
41 mbPageIsFocused(false),
42 mbIsVerticalWrapActive(false)
44 if (mrSlideSorter.GetModel().GetPageCount() > 0)
45 mnPageIndex = 0;
48 FocusManager::~FocusManager()
52 void FocusManager::MoveFocus (FocusMoveDirection eDirection)
54 if (mnPageIndex >= 0 && mbPageIsFocused)
56 HideFocusIndicator (GetFocusedPageDescriptor());
58 const sal_Int32 nColumnCount (mrSlideSorter.GetView().GetLayouter().GetColumnCount());
59 const sal_Int32 nPageCount (mrSlideSorter.GetModel().GetPageCount());
60 switch (eDirection)
62 case FMD_NONE:
63 // Nothing to be done.
64 break;
66 case FMD_LEFT:
67 if (mnPageIndex > 0)
68 mnPageIndex -= 1;
69 else if (mbIsVerticalWrapActive)
70 mnPageIndex = nPageCount-1;
71 break;
73 case FMD_RIGHT:
74 if (mnPageIndex < nPageCount-1)
75 mnPageIndex += 1;
76 else if (mbIsVerticalWrapActive)
77 mnPageIndex = 0;
78 break;
80 case FMD_UP:
82 const sal_Int32 nCandidate (mnPageIndex - nColumnCount);
83 if (nCandidate < 0)
85 if (mbIsVerticalWrapActive)
87 // Wrap around to the bottom row or the one above
88 // and go to the correct column.
89 const sal_Int32 nLastIndex (nPageCount-1);
90 const sal_Int32 nLastColumn (nLastIndex % nColumnCount);
91 const sal_Int32 nCurrentColumn (mnPageIndex%nColumnCount);
92 if (nLastColumn >= nCurrentColumn)
94 // The last row contains the current column.
95 mnPageIndex = nLastIndex - (nLastColumn-nCurrentColumn);
97 else
99 // Only the second to last row contains the current column.
100 mnPageIndex = nLastIndex - nLastColumn
101 - nColumnCount
102 + nCurrentColumn;
106 else
108 // Move the focus the previous row.
109 mnPageIndex = nCandidate;
112 break;
114 case FMD_DOWN:
116 const sal_Int32 nCandidate (mnPageIndex + nColumnCount);
117 if (nCandidate >= nPageCount)
119 if (mbIsVerticalWrapActive)
121 // Wrap around to the correct column.
122 mnPageIndex = mnPageIndex % nColumnCount;
124 else
126 // Do not move the focus.
129 else
131 // Move the focus to the next row.
132 mnPageIndex = nCandidate;
135 break;
138 if (mnPageIndex < 0)
140 OSL_ASSERT(mnPageIndex>=0);
141 mnPageIndex = 0;
143 else if (mnPageIndex >= nPageCount)
145 OSL_ASSERT(mnPageIndex<nPageCount);
146 mnPageIndex = nPageCount - 1;
149 if (mbPageIsFocused)
151 ShowFocusIndicator(GetFocusedPageDescriptor(), true);
156 void FocusManager::ShowFocus (const bool bScrollToFocus)
158 mbPageIsFocused = true;
159 ShowFocusIndicator(GetFocusedPageDescriptor(), bScrollToFocus);
162 void FocusManager::HideFocus()
164 mbPageIsFocused = false;
165 HideFocusIndicator(GetFocusedPageDescriptor());
168 bool FocusManager::ToggleFocus()
170 if (mnPageIndex >= 0)
172 if (mbPageIsFocused)
173 HideFocus ();
174 else
175 ShowFocus ();
177 return mbPageIsFocused;
180 bool FocusManager::HasFocus() const
182 return mrSlideSorter.GetContentWindow()->HasFocus();
185 model::SharedPageDescriptor FocusManager::GetFocusedPageDescriptor() const
187 return mrSlideSorter.GetModel().GetPageDescriptor(mnPageIndex);
190 void FocusManager::SetFocusedPage (const model::SharedPageDescriptor& rpDescriptor)
192 if (rpDescriptor.get() != NULL)
194 FocusHider aFocusHider (*this);
195 mnPageIndex = (rpDescriptor->GetPage()->GetPageNum()-1)/2;
199 void FocusManager::SetFocusedPage (sal_Int32 nPageIndex)
201 FocusHider aFocusHider (*this);
202 mnPageIndex = nPageIndex;
205 void FocusManager::SetFocusedPageToCurrentPage()
207 SetFocusedPage(mrSlideSorter.GetController().GetCurrentSlideManager()->GetCurrentSlide());
210 bool FocusManager::IsFocusShowing() const
212 return HasFocus() && mbPageIsFocused;
215 void FocusManager::HideFocusIndicator (const model::SharedPageDescriptor& rpDescriptor)
217 if (rpDescriptor.get() != NULL)
219 mrSlideSorter.GetView().SetState(rpDescriptor, model::PageDescriptor::ST_Focused, false);
221 // Hide focus should also fire the focus event, Currently, only accessibility add the focus listener
222 NotifyFocusChangeListeners();
226 void FocusManager::ShowFocusIndicator (
227 const model::SharedPageDescriptor& rpDescriptor,
228 const bool bScrollToFocus)
230 if (rpDescriptor.get() != NULL)
232 mrSlideSorter.GetView().SetState(rpDescriptor, model::PageDescriptor::ST_Focused, true);
234 if (bScrollToFocus)
236 // Scroll the focused page object into the visible area and repaint
237 // it, so that the focus indicator becomes visible.
238 mrSlideSorter.GetController().GetVisibleAreaManager().RequestVisible(rpDescriptor,true);
240 mrSlideSorter.GetView().RequestRepaint(rpDescriptor);
242 NotifyFocusChangeListeners();
246 void FocusManager::AddFocusChangeListener (const Link<>& rListener)
248 if (::std::find (maFocusChangeListeners.begin(), maFocusChangeListeners.end(), rListener)
249 == maFocusChangeListeners.end())
251 maFocusChangeListeners.push_back (rListener);
255 void FocusManager::RemoveFocusChangeListener (const Link<>& rListener)
257 maFocusChangeListeners.erase (
258 ::std::find (maFocusChangeListeners.begin(), maFocusChangeListeners.end(), rListener));
261 void FocusManager::NotifyFocusChangeListeners() const
263 // Create a copy of the listener list to be safe when that is modified.
264 ::std::vector<Link<>> aListeners (maFocusChangeListeners);
266 // Tell the selection change listeners that the selection has changed.
267 ::std::vector<Link<>>::iterator iListener (aListeners.begin());
268 ::std::vector<Link<>>::iterator iEnd (aListeners.end());
269 for (; iListener!=iEnd; ++iListener)
271 iListener->Call(NULL);
275 FocusManager::FocusHider::FocusHider (FocusManager& rManager)
276 : mbFocusVisible(rManager.IsFocusShowing())
277 , mrManager(rManager)
279 mrManager.HideFocus();
282 FocusManager::FocusHider::~FocusHider()
284 if (mbFocusVisible)
285 mrManager.ShowFocus();
288 } } } // end of namespace ::sd::slidesorter::controller
290 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */