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 // Hide focus should also fire the focus event, Currently, only accessibility add the focus listener 289 NotifyFocusChangeListeners(); 290 } 291 } 292 293 294 295 296 void FocusManager::ShowFocusIndicator ( 297 const model::SharedPageDescriptor& rpDescriptor, 298 const bool bScrollToFocus) 299 { 300 if (rpDescriptor.get() != NULL) 301 { 302 mrSlideSorter.GetView().SetState(rpDescriptor, model::PageDescriptor::ST_Focused, true); 303 304 if (bScrollToFocus) 305 { 306 // Scroll the focused page object into the visible area and repaint 307 // it, so that the focus indicator becomes visible. 308 mrSlideSorter.GetController().GetVisibleAreaManager().RequestVisible(rpDescriptor,true); 309 } 310 mrSlideSorter.GetView().RequestRepaint(rpDescriptor); 311 312 NotifyFocusChangeListeners(); 313 } 314 } 315 316 317 318 319 void FocusManager::AddFocusChangeListener (const Link& rListener) 320 { 321 if (::std::find (maFocusChangeListeners.begin(), maFocusChangeListeners.end(), rListener) 322 == maFocusChangeListeners.end()) 323 { 324 maFocusChangeListeners.push_back (rListener); 325 } 326 } 327 328 329 330 331 void FocusManager::RemoveFocusChangeListener (const Link& rListener) 332 { 333 maFocusChangeListeners.erase ( 334 ::std::find (maFocusChangeListeners.begin(), maFocusChangeListeners.end(), rListener)); 335 } 336 337 338 339 340 void FocusManager::SetFocusToToolBox (void) 341 { 342 HideFocus(); 343 344 if (mrSlideSorter.GetViewShell() != NULL) 345 { 346 ::Window* pParentWindow = mrSlideSorter.GetViewShell()->GetParentWindow(); 347 DockingWindow* pDockingWindow = NULL; 348 while (pParentWindow!=NULL && pDockingWindow==NULL) 349 { 350 pDockingWindow = dynamic_cast<DockingWindow*>(pParentWindow); 351 pParentWindow = pParentWindow->GetParent(); 352 } 353 if (pDockingWindow) 354 { 355 PaneDockingWindow* pPaneDockingWindow = dynamic_cast<PaneDockingWindow*>(pDockingWindow); 356 if (pPaneDockingWindow != NULL) 357 pPaneDockingWindow->GetToolBox().GrabFocus(); 358 } 359 } 360 } 361 362 363 364 365 void FocusManager::NotifyFocusChangeListeners (void) const 366 { 367 // Create a copy of the listener list to be safe when that is modified. 368 ::std::vector<Link> aListeners (maFocusChangeListeners); 369 370 // Tell the slection change listeners that the selection has changed. 371 ::std::vector<Link>::iterator iListener (aListeners.begin()); 372 ::std::vector<Link>::iterator iEnd (aListeners.end()); 373 for (; iListener!=iEnd; ++iListener) 374 { 375 iListener->Call(NULL); 376 } 377 } 378 379 380 381 382 FocusManager::FocusHider::FocusHider (FocusManager& rManager) 383 : mbFocusVisible(rManager.IsFocusShowing()) 384 , mrManager(rManager) 385 { 386 mrManager.HideFocus(); 387 } 388 389 390 391 392 FocusManager::FocusHider::~FocusHider (void) 393 { 394 if (mbFocusVisible) 395 mrManager.ShowFocus(); 396 } 397 398 } } } // end of namespace ::sd::slidesorter::controller 399 400