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 // MARKER(update_precomp.py): autogen include statement, do not remove 25 #include "precompiled_sdext.hxx" 26 27 #include "PresenterPaneBase.hxx" 28 #include "PresenterCanvasHelper.hxx" 29 #include "PresenterController.hxx" 30 #include "PresenterGeometryHelper.hxx" 31 #include "PresenterPaintManager.hxx" 32 #include "PresenterTextView.hxx" 33 #include <com/sun/star/awt/PosSize.hpp> 34 #include <com/sun/star/awt/XWindow2.hpp> 35 #include <com/sun/star/awt/XWindowPeer.hpp> 36 #include <com/sun/star/lang/XMultiComponentFactory.hpp> 37 #include <com/sun/star/drawing/CanvasFeature.hpp> 38 #include <com/sun/star/rendering/CompositeOperation.hpp> 39 #include <com/sun/star/rendering/TexturingMode.hpp> 40 #include <osl/mutex.hxx> 41 42 using namespace ::com::sun::star; 43 using namespace ::com::sun::star::uno; 44 using namespace ::com::sun::star::drawing::framework; 45 using ::rtl::OUString; 46 47 namespace sdext { namespace presenter { 48 49 //===== PresenterPaneBase ===================================================== 50 51 PresenterPaneBase::PresenterPaneBase ( 52 const Reference<XComponentContext>& rxContext, 53 const ::rtl::Reference<PresenterController>& rpPresenterController) 54 : PresenterPaneBaseInterfaceBase(m_aMutex), 55 mpPresenterController(rpPresenterController), 56 mxParentWindow(), 57 mxBorderWindow(), 58 mxBorderCanvas(), 59 mxContentWindow(), 60 mxContentCanvas(), 61 mxPaneId(), 62 mxBorderPainter(), 63 mxPresenterHelper(), 64 msTitle(), 65 mxComponentContext(rxContext), 66 mpViewBackground(), 67 mbHasCallout(false), 68 maCalloutAnchor() 69 { 70 if (mpPresenterController.get() != NULL) 71 mxPresenterHelper = mpPresenterController->GetPresenterHelper(); 72 } 73 74 75 76 77 PresenterPaneBase::~PresenterPaneBase (void) 78 { 79 } 80 81 82 83 84 void PresenterPaneBase::disposing (void) 85 { 86 if (mxBorderWindow.is()) 87 { 88 mxBorderWindow->removeWindowListener(this); 89 mxBorderWindow->removePaintListener(this); 90 } 91 92 { 93 Reference<XComponent> xComponent (mxContentCanvas, UNO_QUERY); 94 mxContentCanvas = NULL; 95 if (xComponent.is()) 96 xComponent->dispose(); 97 } 98 99 { 100 Reference<XComponent> xComponent (mxContentWindow, UNO_QUERY); 101 mxContentWindow = NULL; 102 if (xComponent.is()) 103 xComponent->dispose(); 104 } 105 106 { 107 Reference<XComponent> xComponent (mxBorderCanvas, UNO_QUERY); 108 mxBorderCanvas = NULL; 109 if (xComponent.is()) 110 xComponent->dispose(); 111 } 112 113 { 114 Reference<XComponent> xComponent (mxBorderWindow, UNO_QUERY); 115 mxBorderWindow = NULL; 116 if (xComponent.is()) 117 xComponent->dispose(); 118 } 119 120 mxComponentContext = NULL; 121 } 122 123 124 125 126 void PresenterPaneBase::SetTitle (const OUString& rsTitle) 127 { 128 msTitle = rsTitle; 129 130 OSL_ASSERT(mpPresenterController.get()!=NULL); 131 OSL_ASSERT(mpPresenterController->GetPaintManager().get()!=NULL); 132 133 mpPresenterController->GetPaintManager()->Invalidate(mxBorderWindow); 134 } 135 136 137 138 139 ::rtl::OUString PresenterPaneBase::GetTitle (void) const 140 { 141 return msTitle; 142 } 143 144 145 146 147 Reference<drawing::framework::XPaneBorderPainter> 148 PresenterPaneBase::GetPaneBorderPainter (void) const 149 { 150 return mxBorderPainter; 151 } 152 153 154 155 156 void PresenterPaneBase::SetCalloutAnchor (const css::awt::Point& rCalloutAnchor) 157 { 158 mbHasCallout = true; 159 // Anchor is given in the coorindate system of the parent window. 160 // Transform it into the local coordinate system. 161 maCalloutAnchor = rCalloutAnchor; 162 const awt::Rectangle aBorderBox (mxBorderWindow->getPosSize()); 163 maCalloutAnchor.X -= aBorderBox.X; 164 maCalloutAnchor.Y -= aBorderBox.Y; 165 166 // Move the bottom of the border window so that it goes through the 167 // callout anchor (special case for bottom callout). 168 sal_Int32 nHeight (rCalloutAnchor.Y - aBorderBox.Y); 169 if (mxBorderPainter.is() && mxPaneId.is()) 170 nHeight += mxBorderPainter->getCalloutOffset(mxPaneId->getResourceURL()).Y; 171 172 if (nHeight != aBorderBox.Height) 173 { 174 mxBorderWindow->setPosSize( 175 aBorderBox.X, 176 aBorderBox.Y, 177 aBorderBox.Width, 178 nHeight, 179 awt::PosSize::HEIGHT); 180 } 181 182 mpPresenterController->GetPaintManager()->Invalidate(mxBorderWindow); 183 } 184 185 186 187 188 awt::Point PresenterPaneBase::GetCalloutAnchor (void) const 189 { 190 return maCalloutAnchor; 191 } 192 193 194 195 196 ::boost::shared_ptr<PresenterTextView> PresenterPaneBase::GetTextViewForTitle (void) 197 { 198 ::boost::shared_ptr<PresenterTextView> pTextView( 199 new PresenterTextView( 200 mxComponentContext, 201 mxBorderCanvas)); 202 pTextView->SetText(msTitle); 203 return pTextView; 204 } 205 206 207 208 209 //----- XInitialization ------------------------------------------------------- 210 211 void SAL_CALL PresenterPaneBase::initialize (const Sequence<Any>& rArguments) 212 throw (Exception, RuntimeException) 213 { 214 ThrowIfDisposed(); 215 216 if ( ! mxComponentContext.is()) 217 { 218 throw RuntimeException( 219 OUString::createFromAscii("PresenterSpritePane: missing component context"), 220 static_cast<XWeak*>(this)); 221 } 222 223 if (rArguments.getLength() == 5 || rArguments.getLength() == 6) 224 { 225 try 226 { 227 // Get the resource id from the first argument. 228 if ( ! (rArguments[0] >>= mxPaneId)) 229 { 230 throw lang::IllegalArgumentException( 231 OUString::createFromAscii("PresenterPane: invalid pane id"), 232 static_cast<XWeak*>(this), 233 0); 234 } 235 236 if ( ! (rArguments[1] >>= mxParentWindow)) 237 { 238 throw lang::IllegalArgumentException( 239 OUString::createFromAscii("PresenterPane: invalid parent window"), 240 static_cast<XWeak*>(this), 241 1); 242 } 243 244 Reference<rendering::XSpriteCanvas> xParentCanvas; 245 if ( ! (rArguments[2] >>= xParentCanvas)) 246 { 247 throw lang::IllegalArgumentException( 248 OUString::createFromAscii("PresenterPane: invalid parent canvas"), 249 static_cast<XWeak*>(this), 250 2); 251 } 252 253 if ( ! (rArguments[3] >>= msTitle)) 254 { 255 throw lang::IllegalArgumentException( 256 OUString::createFromAscii("PresenterPane: invalid title"), 257 static_cast<XWeak*>(this), 258 3); 259 } 260 261 if ( ! (rArguments[4] >>= mxBorderPainter)) 262 { 263 throw lang::IllegalArgumentException( 264 OUString::createFromAscii("PresenterPane: invalid border painter"), 265 static_cast<XWeak*>(this), 266 4); 267 } 268 269 bool bIsWindowVisibleOnCreation (true); 270 if (rArguments.getLength()>5 && ! (rArguments[5] >>= bIsWindowVisibleOnCreation)) 271 { 272 throw lang::IllegalArgumentException( 273 OUString::createFromAscii("PresenterPane: invalid window visibility flag"), 274 static_cast<XWeak*>(this), 275 5); 276 } 277 278 CreateWindows(mxParentWindow, bIsWindowVisibleOnCreation); 279 280 if (mxBorderWindow.is()) 281 { 282 mxBorderWindow->addWindowListener(this); 283 mxBorderWindow->addPaintListener(this); 284 } 285 286 CreateCanvases(mxParentWindow, xParentCanvas); 287 288 // Raise new windows. 289 ToTop(); 290 } 291 catch (Exception&) 292 { 293 mxContentWindow = NULL; 294 mxComponentContext = NULL; 295 throw; 296 } 297 } 298 else 299 { 300 throw RuntimeException( 301 OUString::createFromAscii("PresenterSpritePane: invalid number of arguments"), 302 static_cast<XWeak*>(this)); 303 } 304 } 305 306 307 308 309 //----- XResourceId ----------------------------------------------------------- 310 311 Reference<XResourceId> SAL_CALL PresenterPaneBase::getResourceId (void) 312 throw (RuntimeException) 313 { 314 ThrowIfDisposed(); 315 return mxPaneId; 316 } 317 318 319 320 321 sal_Bool SAL_CALL PresenterPaneBase::isAnchorOnly (void) 322 throw (RuntimeException) 323 { 324 return true; 325 } 326 327 328 329 330 //----- XWindowListener ------------------------------------------------------- 331 332 void SAL_CALL PresenterPaneBase::windowResized (const awt::WindowEvent& rEvent) 333 throw (RuntimeException) 334 { 335 (void)rEvent; 336 ThrowIfDisposed(); 337 } 338 339 340 341 342 343 void SAL_CALL PresenterPaneBase::windowMoved (const awt::WindowEvent& rEvent) 344 throw (RuntimeException) 345 { 346 (void)rEvent; 347 ThrowIfDisposed(); 348 } 349 350 351 352 353 void SAL_CALL PresenterPaneBase::windowShown (const lang::EventObject& rEvent) 354 throw (RuntimeException) 355 { 356 (void)rEvent; 357 ThrowIfDisposed(); 358 } 359 360 361 362 363 void SAL_CALL PresenterPaneBase::windowHidden (const lang::EventObject& rEvent) 364 throw (RuntimeException) 365 { 366 (void)rEvent; 367 ThrowIfDisposed(); 368 } 369 370 371 372 373 //----- lang::XEventListener -------------------------------------------------- 374 375 void SAL_CALL PresenterPaneBase::disposing (const lang::EventObject& rEvent) 376 throw (RuntimeException) 377 { 378 if (rEvent.Source == mxBorderWindow) 379 { 380 mxBorderWindow = NULL; 381 } 382 } 383 384 385 386 387 //----------------------------------------------------------------------------- 388 389 390 void PresenterPaneBase::CreateWindows ( 391 const Reference<awt::XWindow>& rxParentWindow, 392 const bool bIsWindowVisibleOnCreation) 393 { 394 if (mxPresenterHelper.is() && rxParentWindow.is()) 395 { 396 397 mxBorderWindow = mxPresenterHelper->createWindow( 398 rxParentWindow, 399 sal_False, 400 bIsWindowVisibleOnCreation, 401 sal_False, 402 sal_False); 403 mxContentWindow = mxPresenterHelper->createWindow( 404 mxBorderWindow, 405 sal_False, 406 bIsWindowVisibleOnCreation, 407 sal_False, 408 sal_False); 409 } 410 } 411 412 413 414 415 Reference<awt::XWindow> PresenterPaneBase::GetBorderWindow (void) const 416 { 417 return mxBorderWindow; 418 } 419 420 421 422 423 void PresenterPaneBase::ToTop (void) 424 { 425 if (mxPresenterHelper.is()) 426 mxPresenterHelper->toTop(mxContentWindow); 427 } 428 429 430 431 432 void PresenterPaneBase::SetBackground (const SharedBitmapDescriptor& rpBackground) 433 { 434 mpViewBackground = rpBackground; 435 } 436 437 438 439 440 void PresenterPaneBase::PaintBorderBackground ( 441 const awt::Rectangle& rBorderBox, 442 const awt::Rectangle& rUpdateBox) 443 { 444 (void)rBorderBox; 445 (void)rUpdateBox; 446 /* 447 // The outer box of the border is given. We need the center and inner 448 // box as well. 449 awt::Rectangle aCenterBox ( 450 mxBorderPainter->removeBorder( 451 mxPaneId->getResourceURL(), 452 rBorderBox, 453 drawing::framework::BorderType_OUTER_BORDER)); 454 awt::Rectangle aInnerBox ( 455 mxBorderPainter->removeBorder( 456 mxPaneId->getResourceURL(), 457 rBorderBox, 458 drawing::framework::BorderType_TOTAL_BORDER)); 459 mpPresenterController->GetCanvasHelper()->Paint( 460 mpViewBackground, 461 mxBorderCanvas, 462 rUpdateBox, 463 aCenterBox, 464 aInnerBox); 465 */ 466 } 467 468 469 470 471 void PresenterPaneBase::PaintBorder (const awt::Rectangle& rUpdateBox) 472 { 473 OSL_ASSERT(mxPaneId.is()); 474 475 if (mxBorderPainter.is() && mxBorderWindow.is() && mxBorderCanvas.is()) 476 { 477 awt::Rectangle aBorderBox (mxBorderWindow->getPosSize()); 478 awt::Rectangle aLocalBorderBox (0,0, aBorderBox.Width, aBorderBox.Height); 479 480 PaintBorderBackground(aLocalBorderBox, rUpdateBox); 481 482 if (mbHasCallout) 483 mxBorderPainter->paintBorderWithCallout( 484 mxPaneId->getResourceURL(), 485 mxBorderCanvas, 486 aLocalBorderBox, 487 rUpdateBox, 488 msTitle, 489 maCalloutAnchor); 490 else 491 mxBorderPainter->paintBorder( 492 mxPaneId->getResourceURL(), 493 mxBorderCanvas, 494 aLocalBorderBox, 495 rUpdateBox, 496 msTitle); 497 } 498 } 499 500 501 502 503 void PresenterPaneBase::LayoutContextWindow (void) 504 { 505 OSL_ASSERT(mxPaneId.is()); 506 OSL_ASSERT(mxBorderWindow.is()); 507 OSL_ASSERT(mxContentWindow.is()); 508 if (mxBorderPainter.is() && mxPaneId.is() && mxBorderWindow.is() && mxContentWindow.is()) 509 { 510 const awt::Rectangle aBorderBox (mxBorderWindow->getPosSize()); 511 const awt::Rectangle aInnerBox (mxBorderPainter->removeBorder( 512 mxPaneId->getResourceURL(), 513 aBorderBox, 514 drawing::framework::BorderType_TOTAL_BORDER)); 515 mxContentWindow->setPosSize( 516 aInnerBox.X - aBorderBox.X, 517 aInnerBox.Y - aBorderBox.Y, 518 aInnerBox.Width, 519 aInnerBox.Height, 520 awt::PosSize::POSSIZE); 521 } 522 } 523 524 525 526 527 bool PresenterPaneBase::IsVisible (void) const 528 { 529 Reference<awt::XWindow2> xWindow2 (mxBorderPainter, UNO_QUERY); 530 if (xWindow2.is()) 531 return xWindow2->isVisible(); 532 533 return false; 534 } 535 536 537 538 539 void PresenterPaneBase::ThrowIfDisposed (void) 540 throw (::com::sun::star::lang::DisposedException) 541 { 542 if (rBHelper.bDisposed || rBHelper.bInDispose) 543 { 544 throw lang::DisposedException ( 545 ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM( 546 "PresenterPane object has already been disposed")), 547 static_cast<uno::XWeak*>(this)); 548 } 549 } 550 551 552 553 554 } } // end of namespace ::sd::presenter 555