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