1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
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 <controller/SlideSorterController.hxx>
24 #include <controller/SlsCurrentSlideManager.hxx>
25 #include <controller/SlsVisibleAreaManager.hxx>
26 #include <model/SlideSorterModel.hxx>
27 #include <model/SlsPageDescriptor.hxx>
28 #include <view/SlideSorterView.hxx>
29 #include <view/SlsLayouter.hxx>
30 #include <osl/diagnose.h>
35 namespace sd::slidesorter::controller
{
37 FocusManager::FocusManager (SlideSorter
& rSlideSorter
)
38 : mrSlideSorter(rSlideSorter
),
40 mbPageIsFocused(false)
42 if (mrSlideSorter
.GetModel().GetPageCount() > 0)
46 FocusManager::~FocusManager()
50 void FocusManager::MoveFocus (FocusMoveDirection eDirection
)
52 if (!(mnPageIndex
>= 0 && mbPageIsFocused
))
55 HideFocusIndicator (GetFocusedPageDescriptor());
57 const sal_Int32
nColumnCount (mrSlideSorter
.GetView().GetLayouter().GetColumnCount());
58 const sal_Int32
nPageCount (mrSlideSorter
.GetModel().GetPageCount());
61 case FocusMoveDirection::Left
:
66 case FocusMoveDirection::Right
:
67 if (mnPageIndex
< nPageCount
-1)
71 case FocusMoveDirection::Up
:
73 const sal_Int32
nCandidate (mnPageIndex
- nColumnCount
);
76 // Move the focus the previous row.
77 mnPageIndex
= nCandidate
;
82 case FocusMoveDirection::Down
:
84 const sal_Int32
nCandidate (mnPageIndex
+ nColumnCount
);
85 if (nCandidate
< nPageCount
)
87 // Move the focus to the next row.
88 mnPageIndex
= nCandidate
;
96 OSL_ASSERT(mnPageIndex
>=0);
99 else if (mnPageIndex
>= nPageCount
)
101 OSL_ASSERT(mnPageIndex
<nPageCount
);
102 mnPageIndex
= nPageCount
- 1;
107 ShowFocusIndicator(GetFocusedPageDescriptor(), true);
111 void FocusManager::ShowFocus (const bool bScrollToFocus
)
113 mbPageIsFocused
= true;
114 ShowFocusIndicator(GetFocusedPageDescriptor(), bScrollToFocus
);
117 void FocusManager::HideFocus()
119 mbPageIsFocused
= false;
120 HideFocusIndicator(GetFocusedPageDescriptor());
123 bool FocusManager::ToggleFocus()
125 if (mnPageIndex
>= 0)
132 return mbPageIsFocused
;
135 bool FocusManager::HasFocus() const
137 return mrSlideSorter
.GetContentWindow()->HasFocus();
140 model::SharedPageDescriptor
FocusManager::GetFocusedPageDescriptor() const
142 return mrSlideSorter
.GetModel().GetPageDescriptor(mnPageIndex
);
145 bool FocusManager::SetFocusedPage (const model::SharedPageDescriptor
& rpDescriptor
)
149 FocusHider
aFocusHider (*this);
150 mnPageIndex
= (rpDescriptor
->GetPage()->GetPageNum()-1)/2;
156 void FocusManager::SetFocusedPage (sal_Int32 nPageIndex
)
158 FocusHider
aFocusHider (*this);
159 mnPageIndex
= nPageIndex
;
162 bool FocusManager::SetFocusedPageFromCurrentPage()
164 return SetFocusedPage(mrSlideSorter
.GetController().GetCurrentSlideManager()->GetCurrentSlide());
167 bool FocusManager::IsFocusShowing() const
169 return HasFocus() && mbPageIsFocused
;
172 void FocusManager::HideFocusIndicator (const model::SharedPageDescriptor
& rpDescriptor
)
176 mrSlideSorter
.GetView().SetState(rpDescriptor
, model::PageDescriptor::ST_Focused
, false);
178 // Hide focus should also fire the focus event, Currently, only accessibility add the focus listener
179 NotifyFocusChangeListeners();
183 void FocusManager::ShowFocusIndicator (
184 const model::SharedPageDescriptor
& rpDescriptor
,
185 const bool bScrollToFocus
)
190 mrSlideSorter
.GetView().SetState(rpDescriptor
, model::PageDescriptor::ST_Focused
, true);
194 // Scroll the focused page object into the visible area and repaint
195 // it, so that the focus indicator becomes visible.
196 mrSlideSorter
.GetController().GetVisibleAreaManager().RequestVisible(rpDescriptor
,true);
198 mrSlideSorter
.GetView().RequestRepaint(rpDescriptor
);
200 NotifyFocusChangeListeners();
203 void FocusManager::AddFocusChangeListener (const Link
<LinkParamNone
*,void>& rListener
)
205 if (::std::find (maFocusChangeListeners
.begin(), maFocusChangeListeners
.end(), rListener
)
206 == maFocusChangeListeners
.end())
208 maFocusChangeListeners
.push_back (rListener
);
212 void FocusManager::RemoveFocusChangeListener (const Link
<LinkParamNone
*,void>& rListener
)
214 maFocusChangeListeners
.erase (
215 ::std::find (maFocusChangeListeners
.begin(), maFocusChangeListeners
.end(), rListener
));
218 void FocusManager::NotifyFocusChangeListeners() const
220 // Create a copy of the listener list to be safe when that is modified.
221 ::std::vector
<Link
<LinkParamNone
*,void>> aListeners (maFocusChangeListeners
);
223 // Tell the selection change listeners that the selection has changed.
224 for (const auto& rListener
: aListeners
)
226 rListener
.Call(nullptr);
230 FocusManager::FocusHider::FocusHider (FocusManager
& rManager
)
231 : mbFocusVisible(rManager
.IsFocusShowing())
232 , mrManager(rManager
)
234 mrManager
.HideFocus();
237 FocusManager::FocusHider::~FocusHider() COVERITY_NOEXCEPT_FALSE
240 mrManager
.ShowFocus();
243 } // end of namespace ::sd::slidesorter::controller
245 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */