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 { 213 ThrowIfDisposed(); 214 215 if ( ! mxComponentContext.is()) 216 { 217 throw RuntimeException( 218 OUString::createFromAscii("PresenterSpritePane: missing component context"), 219 static_cast<XWeak*>(this)); 220 } 221 222 if (rArguments.getLength() == 5 || rArguments.getLength() == 6) 223 { 224 try 225 { 226 // Get the resource id from the first argument. 227 if ( ! (rArguments[0] >>= mxPaneId)) 228 { 229 throw lang::IllegalArgumentException( 230 OUString::createFromAscii("PresenterPane: invalid pane id"), 231 static_cast<XWeak*>(this), 232 0); 233 } 234 235 if ( ! (rArguments[1] >>= mxParentWindow)) 236 { 237 throw lang::IllegalArgumentException( 238 OUString::createFromAscii("PresenterPane: invalid parent window"), 239 static_cast<XWeak*>(this), 240 1); 241 } 242 243 Reference<rendering::XSpriteCanvas> xParentCanvas; 244 if ( ! (rArguments[2] >>= xParentCanvas)) 245 { 246 throw lang::IllegalArgumentException( 247 OUString::createFromAscii("PresenterPane: invalid parent canvas"), 248 static_cast<XWeak*>(this), 249 2); 250 } 251 252 if ( ! (rArguments[3] >>= msTitle)) 253 { 254 throw lang::IllegalArgumentException( 255 OUString::createFromAscii("PresenterPane: invalid title"), 256 static_cast<XWeak*>(this), 257 3); 258 } 259 260 if ( ! (rArguments[4] >>= mxBorderPainter)) 261 { 262 throw lang::IllegalArgumentException( 263 OUString::createFromAscii("PresenterPane: invalid border painter"), 264 static_cast<XWeak*>(this), 265 4); 266 } 267 268 bool bIsWindowVisibleOnCreation (true); 269 if (rArguments.getLength()>5 && ! (rArguments[5] >>= bIsWindowVisibleOnCreation)) 270 { 271 throw lang::IllegalArgumentException( 272 OUString::createFromAscii("PresenterPane: invalid window visibility flag"), 273 static_cast<XWeak*>(this), 274 5); 275 } 276 277 CreateWindows(mxParentWindow, bIsWindowVisibleOnCreation); 278 279 if (mxBorderWindow.is()) 280 { 281 mxBorderWindow->addWindowListener(this); 282 mxBorderWindow->addPaintListener(this); 283 } 284 285 CreateCanvases(mxParentWindow, xParentCanvas); 286 287 // Raise new windows. 288 ToTop(); 289 } 290 catch (Exception&) 291 { 292 mxContentWindow = NULL; 293 mxComponentContext = NULL; 294 throw; 295 } 296 } 297 else 298 { 299 throw RuntimeException( 300 OUString::createFromAscii("PresenterSpritePane: invalid number of arguments"), 301 static_cast<XWeak*>(this)); 302 } 303 } 304 305 306 307 308 //----- XResourceId ----------------------------------------------------------- 309 310 Reference<XResourceId> SAL_CALL PresenterPaneBase::getResourceId (void) 311 { 312 ThrowIfDisposed(); 313 return mxPaneId; 314 } 315 316 317 318 319 sal_Bool SAL_CALL PresenterPaneBase::isAnchorOnly (void) 320 { 321 return true; 322 } 323 324 325 326 327 //----- XWindowListener ------------------------------------------------------- 328 329 void SAL_CALL PresenterPaneBase::windowResized (const awt::WindowEvent& rEvent) 330 { 331 (void)rEvent; 332 ThrowIfDisposed(); 333 } 334 335 336 337 338 339 void SAL_CALL PresenterPaneBase::windowMoved (const awt::WindowEvent& rEvent) 340 { 341 (void)rEvent; 342 ThrowIfDisposed(); 343 } 344 345 346 347 348 void SAL_CALL PresenterPaneBase::windowShown (const lang::EventObject& rEvent) 349 { 350 (void)rEvent; 351 ThrowIfDisposed(); 352 } 353 354 355 356 357 void SAL_CALL PresenterPaneBase::windowHidden (const lang::EventObject& rEvent) 358 { 359 (void)rEvent; 360 ThrowIfDisposed(); 361 } 362 363 364 365 366 //----- lang::XEventListener -------------------------------------------------- 367 368 void SAL_CALL PresenterPaneBase::disposing (const lang::EventObject& rEvent) 369 { 370 if (rEvent.Source == mxBorderWindow) 371 { 372 mxBorderWindow = NULL; 373 } 374 } 375 376 377 378 379 //----------------------------------------------------------------------------- 380 381 382 void PresenterPaneBase::CreateWindows ( 383 const Reference<awt::XWindow>& rxParentWindow, 384 const bool bIsWindowVisibleOnCreation) 385 { 386 if (mxPresenterHelper.is() && rxParentWindow.is()) 387 { 388 389 mxBorderWindow = mxPresenterHelper->createWindow( 390 rxParentWindow, 391 sal_False, 392 bIsWindowVisibleOnCreation, 393 sal_False, 394 sal_False); 395 mxContentWindow = mxPresenterHelper->createWindow( 396 mxBorderWindow, 397 sal_False, 398 bIsWindowVisibleOnCreation, 399 sal_False, 400 sal_False); 401 } 402 } 403 404 405 406 407 Reference<awt::XWindow> PresenterPaneBase::GetBorderWindow (void) const 408 { 409 return mxBorderWindow; 410 } 411 412 413 414 415 void PresenterPaneBase::ToTop (void) 416 { 417 if (mxPresenterHelper.is()) 418 mxPresenterHelper->toTop(mxContentWindow); 419 } 420 421 422 423 424 void PresenterPaneBase::SetBackground (const SharedBitmapDescriptor& rpBackground) 425 { 426 mpViewBackground = rpBackground; 427 } 428 429 430 431 432 void PresenterPaneBase::PaintBorderBackground ( 433 const awt::Rectangle& rBorderBox, 434 const awt::Rectangle& rUpdateBox) 435 { 436 (void)rBorderBox; 437 (void)rUpdateBox; 438 /* 439 // The outer box of the border is given. We need the center and inner 440 // box as well. 441 awt::Rectangle aCenterBox ( 442 mxBorderPainter->removeBorder( 443 mxPaneId->getResourceURL(), 444 rBorderBox, 445 drawing::framework::BorderType_OUTER_BORDER)); 446 awt::Rectangle aInnerBox ( 447 mxBorderPainter->removeBorder( 448 mxPaneId->getResourceURL(), 449 rBorderBox, 450 drawing::framework::BorderType_TOTAL_BORDER)); 451 mpPresenterController->GetCanvasHelper()->Paint( 452 mpViewBackground, 453 mxBorderCanvas, 454 rUpdateBox, 455 aCenterBox, 456 aInnerBox); 457 */ 458 } 459 460 461 462 463 void PresenterPaneBase::PaintBorder (const awt::Rectangle& rUpdateBox) 464 { 465 OSL_ASSERT(mxPaneId.is()); 466 467 if (mxBorderPainter.is() && mxBorderWindow.is() && mxBorderCanvas.is()) 468 { 469 awt::Rectangle aBorderBox (mxBorderWindow->getPosSize()); 470 awt::Rectangle aLocalBorderBox (0,0, aBorderBox.Width, aBorderBox.Height); 471 472 PaintBorderBackground(aLocalBorderBox, rUpdateBox); 473 474 if (mbHasCallout) 475 mxBorderPainter->paintBorderWithCallout( 476 mxPaneId->getResourceURL(), 477 mxBorderCanvas, 478 aLocalBorderBox, 479 rUpdateBox, 480 msTitle, 481 maCalloutAnchor); 482 else 483 mxBorderPainter->paintBorder( 484 mxPaneId->getResourceURL(), 485 mxBorderCanvas, 486 aLocalBorderBox, 487 rUpdateBox, 488 msTitle); 489 } 490 } 491 492 493 494 495 void PresenterPaneBase::LayoutContextWindow (void) 496 { 497 OSL_ASSERT(mxPaneId.is()); 498 OSL_ASSERT(mxBorderWindow.is()); 499 OSL_ASSERT(mxContentWindow.is()); 500 if (mxBorderPainter.is() && mxPaneId.is() && mxBorderWindow.is() && mxContentWindow.is()) 501 { 502 const awt::Rectangle aBorderBox (mxBorderWindow->getPosSize()); 503 const awt::Rectangle aInnerBox (mxBorderPainter->removeBorder( 504 mxPaneId->getResourceURL(), 505 aBorderBox, 506 drawing::framework::BorderType_TOTAL_BORDER)); 507 mxContentWindow->setPosSize( 508 aInnerBox.X - aBorderBox.X, 509 aInnerBox.Y - aBorderBox.Y, 510 aInnerBox.Width, 511 aInnerBox.Height, 512 awt::PosSize::POSSIZE); 513 } 514 } 515 516 517 518 519 bool PresenterPaneBase::IsVisible (void) const 520 { 521 Reference<awt::XWindow2> xWindow2 (mxBorderPainter, UNO_QUERY); 522 if (xWindow2.is()) 523 return xWindow2->isVisible(); 524 525 return false; 526 } 527 528 529 530 531 void PresenterPaneBase::ThrowIfDisposed (void) 532 { 533 if (rBHelper.bDisposed || rBHelper.bInDispose) 534 { 535 throw lang::DisposedException ( 536 ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM( 537 "PresenterPane object has already been disposed")), 538 static_cast<uno::XWeak*>(this)); 539 } 540 } 541 542 543 544 545 } } // end of namespace ::sd::presenter 546