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 #undef ENABLE_PANE_RESIZING
28 //#define ENABLE_PANE_RESIZING
29
30 #include "PresenterWindowManager.hxx"
31 #include "PresenterAnimation.hxx"
32 #include "PresenterAnimator.hxx"
33 #include "PresenterController.hxx"
34 #include "PresenterGeometryHelper.hxx"
35 #include "PresenterHelper.hxx"
36 #include "PresenterPaintManager.hxx"
37 #include "PresenterPaneBase.hxx"
38 #include "PresenterPaneBorderManager.hxx"
39 #include "PresenterPaneBorderPainter.hxx"
40 #include "PresenterPaneContainer.hxx"
41 #include "PresenterPaneFactory.hxx"
42 #include "PresenterSprite.hxx"
43 #include "PresenterToolBar.hxx"
44 #include "PresenterViewFactory.hxx"
45 #include "PresenterTheme.hxx"
46 #include <com/sun/star/awt/InvalidateStyle.hpp>
47 #include <com/sun/star/awt/PosSize.hpp>
48 #include <com/sun/star/awt/SystemPointer.hpp>
49 #include <com/sun/star/awt/XDevice.hpp>
50 #include <com/sun/star/awt/XWindow2.hpp>
51 #include <com/sun/star/awt/XWindowPeer.hpp>
52 #include <com/sun/star/awt/WindowAttribute.hpp>
53 #include <com/sun/star/container/XChild.hpp>
54 #include <com/sun/star/drawing/framework/ResourceId.hpp>
55 #include <com/sun/star/rendering/CompositeOperation.hpp>
56 #include <com/sun/star/rendering/FillRule.hpp>
57 #include <com/sun/star/rendering/PathCapType.hpp>
58 #include <com/sun/star/rendering/PathJoinType.hpp>
59 #include <com/sun/star/rendering/Texture.hpp>
60 #include <com/sun/star/rendering/TexturingMode.hpp>
61 #include <com/sun/star/rendering/XSpriteCanvas.hpp>
62 #include <boost/bind.hpp>
63 #include <boost/bind/protect.hpp>
64 #include <math.h>
65
66 using namespace ::com::sun::star;
67 using namespace ::com::sun::star::uno;
68 using namespace ::com::sun::star::drawing::framework;
69 using ::rtl::OUString;
70
71 #define A2S(pString) (::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(pString)))
72
73 namespace sdext { namespace presenter {
74
75 namespace {
76
77 typedef ::cppu::WeakComponentImplHelper1<
78 css::drawing::framework::XConfigurationChangeListener
79 > ModeChangeAnimationStarterInterfaceBase;
80
81 class ModeChangeAnimationStarter
82 : protected ::cppu::BaseMutex,
83 public ModeChangeAnimationStarterInterfaceBase
84 {
85 public:
86 ModeChangeAnimationStarter (
87 const Reference<drawing::framework::XConfigurationController>& rxConfigurationController,
88 const Reference<awt::XWindow>& rxWindow,
89 const Reference<rendering::XSpriteCanvas>& rxCanvas,
90 const ::boost::shared_ptr<PresenterAnimator>& rpAnimator);
91 virtual ~ModeChangeAnimationStarter (void);
92 virtual void SAL_CALL disposing (void);
93
94 // XConfigurationChangeListener
95
96 virtual void SAL_CALL notifyConfigurationChange (
97 const com::sun::star::drawing::framework::ConfigurationChangeEvent& rEvent)
98 throw (com::sun::star::uno::RuntimeException);
99
100
101 // XEventListener
102
103 virtual void SAL_CALL disposing (
104 const com::sun::star::lang::EventObject& rEvent)
105 throw (com::sun::star::uno::RuntimeException);
106
107 private:
108 Reference<drawing::framework::XConfigurationController> mxConfigurationController;
109 ::boost::shared_ptr<PresenterAnimator> mpAnimator;
110 ::boost::shared_ptr<PresenterSprite> mpSprite;
111 Reference<rendering::XSpriteCanvas> mxCanvas;
112 };
113
114 }
115
116
117
118
119 //===== PresenterWindowManager ================================================
120
PresenterWindowManager(const Reference<XComponentContext> & rxContext,const::rtl::Reference<PresenterPaneContainer> & rpPaneContainer,const::rtl::Reference<PresenterController> & rpPresenterController)121 PresenterWindowManager::PresenterWindowManager (
122 const Reference<XComponentContext>& rxContext,
123 const ::rtl::Reference<PresenterPaneContainer>& rpPaneContainer,
124 const ::rtl::Reference<PresenterController>& rpPresenterController)
125 : PresenterWindowManagerInterfaceBase(m_aMutex),
126 mxComponentContext(rxContext),
127 mpPresenterController(rpPresenterController),
128 mxParentWindow(),
129 mxParentCanvas(),
130 mxPaneBorderManager(),
131 mpPaneBorderPainter(),
132 mpPaneContainer(rpPaneContainer),
133 mbIsLayoutPending(true),
134 mbIsLayouting(false),
135 mpTheme(),
136 mpBackgroundBitmap(),
137 mxScaledBackgroundBitmap(),
138 maPaneBackgroundColor(),
139 mxClipPolygon(),
140 meLayoutMode(LM_Generic),
141 mbIsSlideSorterActive(false),
142 mbIsHelpViewActive(false),
143 maLayoutListeners(),
144 mbIsMouseClickPending(false)
145 {
146 UpdateWindowList();
147 }
148
149
150
151
~PresenterWindowManager(void)152 PresenterWindowManager::~PresenterWindowManager (void)
153 {
154 }
155
156
157
158
disposing(void)159 void SAL_CALL PresenterWindowManager::disposing (void)
160 {
161 NotifyDisposing();
162
163 SetParentPane(NULL);
164
165 Reference<lang::XComponent> xComponent (mxPaneBorderManager, UNO_QUERY);
166 if (xComponent.is())
167 xComponent->dispose();
168 mxPaneBorderManager = NULL;
169
170 PresenterPaneContainer::PaneList::const_iterator iPane;
171 PresenterPaneContainer::PaneList::const_iterator iEnd (mpPaneContainer->maPanes.end());
172 for (iPane=mpPaneContainer->maPanes.begin(); iPane!=iEnd; ++iPane)
173 {
174 if ((*iPane)->mxBorderWindow.is())
175 {
176 (*iPane)->mxBorderWindow->removeWindowListener(this);
177 (*iPane)->mxBorderWindow->removeFocusListener(this);
178 #ifndef ENABLE_PANE_RESIZING
179 (*iPane)->mxBorderWindow->removeMouseListener(this);
180 #endif
181 }
182 }
183 }
184
185
186
187
SetParentPane(const Reference<drawing::framework::XPane> & rxPane)188 void PresenterWindowManager::SetParentPane (
189 const Reference<drawing::framework::XPane>& rxPane)
190 {
191 if (mxParentWindow.is())
192 {
193 mxParentWindow->removeWindowListener(this);
194 mxParentWindow->removePaintListener(this);
195 mxParentWindow->removeMouseListener(this);
196 mxParentWindow->removeFocusListener(this);
197 }
198 mxParentWindow = NULL;
199 mxParentCanvas = NULL;
200
201 if (rxPane.is())
202 {
203 mxParentWindow = rxPane->getWindow();
204 mxParentCanvas = rxPane->getCanvas();
205 }
206 else
207 {
208 mxParentWindow = NULL;
209 }
210
211 if (mxParentWindow.is())
212 {
213 mxParentWindow->addWindowListener(this);
214 mxParentWindow->addPaintListener(this);
215 mxParentWindow->addMouseListener(this);
216 mxParentWindow->addFocusListener(this);
217
218 // We paint our own background, make that of the parent window transparent.
219 Reference<awt::XWindowPeer> xPeer (mxParentWindow, UNO_QUERY);
220 if (xPeer.is())
221 xPeer->setBackground(util::Color(0xff000000));
222 }
223 }
224
225
226
227
SetTheme(const::boost::shared_ptr<PresenterTheme> & rpTheme)228 void PresenterWindowManager::SetTheme (const ::boost::shared_ptr<PresenterTheme>& rpTheme)
229 {
230 mpTheme = rpTheme;
231
232 // Get background bitmap or background color from the theme.
233
234 if (mpTheme.get() != NULL)
235 {
236 mpBackgroundBitmap = mpTheme->GetBitmap(OUString(), A2S("Background"));
237 }
238 }
239
240
241
242
NotifyPaneCreation(const PresenterPaneContainer::SharedPaneDescriptor & rpDescriptor)243 void PresenterWindowManager::NotifyPaneCreation (
244 const PresenterPaneContainer::SharedPaneDescriptor& rpDescriptor)
245 {
246 if (rpDescriptor.get()==NULL)
247 {
248 OSL_ASSERT(rpDescriptor.get()!=NULL);
249 return;
250 }
251 if ( ! rpDescriptor->mxContentWindow.is())
252 {
253 OSL_ASSERT(rpDescriptor->mxContentWindow.is());
254 return;
255 }
256
257 mbIsLayoutPending = true;
258
259 Reference<awt::XWindow> xBorderWindow (rpDescriptor->mxBorderWindow);
260 OSL_ASSERT(xBorderWindow.is());
261 if (xBorderWindow.is() && ! rpDescriptor->mbIsSprite)
262 {
263 Invalidate();
264
265 xBorderWindow->addWindowListener(this);
266 xBorderWindow->addFocusListener(this);
267 #ifndef ENABLE_PANE_RESIZING
268 xBorderWindow->addMouseListener(this);
269 #endif
270 }
271
272 UpdateWindowList();
273 Layout();
274 }
275
276
277
278
NotifyViewCreation(const Reference<XView> & rxView)279 void PresenterWindowManager::NotifyViewCreation (const Reference<XView>& rxView)
280 {
281 PresenterPaneContainer::SharedPaneDescriptor pDescriptor (
282 mpPaneContainer->FindPaneId(rxView->getResourceId()->getAnchor()));
283 OSL_ASSERT(pDescriptor.get() != NULL);
284 if (pDescriptor.get() != NULL)
285 {
286 Layout();
287
288 mpPresenterController->GetPaintManager()->Invalidate(
289 pDescriptor->mxContentWindow,
290 (sal_Int16)(awt::InvalidateStyle::TRANSPARENT
291 | awt::InvalidateStyle::CHILDREN));
292 }
293 }
294
295
296
297
SetPanePosSizeRelative(const Reference<XResourceId> & rxPaneId,const double nRelativeX,const double nRelativeY,const double nRelativeWidth,const double nRelativeHeight)298 void PresenterWindowManager::SetPanePosSizeRelative (
299 const Reference<XResourceId>& rxPaneId,
300 const double nRelativeX,
301 const double nRelativeY,
302 const double nRelativeWidth,
303 const double nRelativeHeight)
304 {
305 PresenterPaneContainer::SharedPaneDescriptor pDescriptor (
306 mpPaneContainer->FindPaneId(rxPaneId));
307 if (pDescriptor.get() != NULL)
308 {
309 pDescriptor->mnLeft = nRelativeX;
310 pDescriptor->mnTop = nRelativeY;
311 pDescriptor->mnRight = nRelativeX + nRelativeWidth;
312 pDescriptor->mnBottom = nRelativeY + nRelativeHeight;
313
314 mpPaneContainer->ToTop(pDescriptor);
315 }
316 }
317
318
319
320
SetPanePosSizeAbsolute(const OUString & rsPaneURL,const double nX,const double nY,const double nWidth,const double nHeight)321 void PresenterWindowManager::SetPanePosSizeAbsolute (
322 const OUString& rsPaneURL,
323 const double nX,
324 const double nY,
325 const double nWidth,
326 const double nHeight)
327 {
328 PresenterPaneContainer::SharedPaneDescriptor pDescriptor (
329 mpPaneContainer->FindPaneURL(rsPaneURL));
330 if (pDescriptor.get() != NULL)
331 {
332 awt::Rectangle aParentBox = mxParentWindow->getPosSize();
333 if (aParentBox.Width > 0 && aParentBox.Height > 0)
334 {
335 pDescriptor->mnLeft = nX / aParentBox.Width;
336 pDescriptor->mnTop = nY / aParentBox.Height;
337 pDescriptor->mnRight = (nX + nWidth) / aParentBox.Width;
338 pDescriptor->mnBottom = (nY + nHeight) / aParentBox.Height;
339 }
340 if (pDescriptor->mxBorderWindow.is())
341 pDescriptor->mxBorderWindow->setPosSize(
342 ::sal::static_int_cast<sal_Int32>(nX),
343 ::sal::static_int_cast<sal_Int32>(nY),
344 ::sal::static_int_cast<sal_Int32>(nWidth),
345 ::sal::static_int_cast<sal_Int32>(nHeight),
346 awt::PosSize::POSSIZE);
347 }
348 }
349
350
351
352
SetPaneBorderPainter(const::rtl::Reference<PresenterPaneBorderPainter> & rPainter)353 void PresenterWindowManager::SetPaneBorderPainter (
354 const ::rtl::Reference<PresenterPaneBorderPainter>& rPainter)
355 {
356 mpPaneBorderPainter = rPainter;
357 }
358
359
360
361
362 //----- XWindowListener -------------------------------------------------------
363
windowResized(const awt::WindowEvent & rEvent)364 void SAL_CALL PresenterWindowManager::windowResized (const awt::WindowEvent& rEvent)
365 throw (RuntimeException)
366 {
367 ThrowIfDisposed();
368 if (rEvent.Source == mxParentWindow)
369 {
370 Layout();
371 }
372 else
373 {
374 Reference<awt::XWindow> xWindow (rEvent.Source,UNO_QUERY);
375 if (xWindow.is())
376 {
377 UpdateWindowSize(xWindow);
378
379 // Make sure the background of a transparent window is painted.
380 mpPresenterController->GetPaintManager()->Invalidate(mxParentWindow);
381 }
382 }
383 }
384
385
386
387
windowMoved(const awt::WindowEvent & rEvent)388 void SAL_CALL PresenterWindowManager::windowMoved (const awt::WindowEvent& rEvent)
389 throw (RuntimeException)
390 {
391 ThrowIfDisposed();
392 if (rEvent.Source != mxParentWindow)
393 {
394 Reference<awt::XWindow> xWindow (rEvent.Source,UNO_QUERY);
395 UpdateWindowSize(xWindow);
396
397 // Make sure the background of a transparent window is painted.
398 mpPresenterController->GetPaintManager()->Invalidate(xWindow);
399 }
400 }
401
402
403
404
windowShown(const lang::EventObject & rEvent)405 void SAL_CALL PresenterWindowManager::windowShown (const lang::EventObject& rEvent)
406 throw (RuntimeException)
407 {
408 (void)rEvent;
409 }
410
411
412
413
windowHidden(const lang::EventObject & rEvent)414 void SAL_CALL PresenterWindowManager::windowHidden (const lang::EventObject& rEvent)
415 throw (RuntimeException)
416 {
417 (void)rEvent;
418 }
419
420
421
422
423 //----- XPaintListener --------------------------------------------------------
424
windowPaint(const awt::PaintEvent & rEvent)425 void SAL_CALL PresenterWindowManager::windowPaint (const awt::PaintEvent& rEvent)
426 throw (RuntimeException)
427 {
428 ThrowIfDisposed();
429
430 if ( ! mxParentWindow.is())
431 return;
432 if ( ! mxParentCanvas.is())
433 return;
434
435 if (mpTheme.get()!=NULL)
436 {
437 try
438 {
439 if (mbIsLayoutPending)
440 Layout();
441 PaintBackground(rEvent.UpdateRect);
442 if ( ! PaintChildren(rEvent))
443 {
444 Reference<rendering::XSpriteCanvas> xSpriteCanvas (mxParentCanvas, UNO_QUERY);
445 // if (xSpriteCanvas.is())
446 // xSpriteCanvas->updateScreen(sal_False);
447 }
448 }
449 catch (RuntimeException&)
450 {
451 OSL_ASSERT(sal_False);
452 }
453 }
454 }
455
456
457
458
459 //----- XMouseListener --------------------------------------------------------
460
mousePressed(const css::awt::MouseEvent & rEvent)461 void SAL_CALL PresenterWindowManager::mousePressed (const css::awt::MouseEvent& rEvent)
462 throw(css::uno::RuntimeException)
463 {
464 (void)rEvent;
465 mbIsMouseClickPending = true;
466 }
467
468
469
470
mouseReleased(const css::awt::MouseEvent & rEvent)471 void SAL_CALL PresenterWindowManager::mouseReleased (const css::awt::MouseEvent& rEvent)
472 throw(css::uno::RuntimeException)
473 {
474 #ifndef ENABLE_PANE_RESIZING
475 if (mbIsMouseClickPending)
476 {
477 mbIsMouseClickPending = false;
478 mpPresenterController->HandleMouseClick(rEvent);
479 }
480 #else
481 (void)rEvent;
482 #endif
483 }
484
485
486
487
mouseEntered(const css::awt::MouseEvent & rEvent)488 void SAL_CALL PresenterWindowManager::mouseEntered (const css::awt::MouseEvent& rEvent)
489 throw(css::uno::RuntimeException)
490 {
491 (void)rEvent;
492 mbIsMouseClickPending = false;
493 }
494
495
496
497
mouseExited(const css::awt::MouseEvent & rEvent)498 void SAL_CALL PresenterWindowManager::mouseExited (const css::awt::MouseEvent& rEvent)
499 throw(css::uno::RuntimeException)
500 {
501 (void)rEvent;
502 mbIsMouseClickPending = false;
503 }
504
505
506
507
508 //----- XFocusListener --------------------------------------------------------
509
focusGained(const css::awt::FocusEvent & rEvent)510 void SAL_CALL PresenterWindowManager::focusGained (const css::awt::FocusEvent& rEvent)
511 throw (css::uno::RuntimeException)
512 {
513 ThrowIfDisposed();
514 (void)rEvent;
515 OSL_TRACE("PresenterWindowManager::focusGained window %x\n",
516 rEvent.Source.get());
517 }
518
519
520
521
focusLost(const css::awt::FocusEvent & rEvent)522 void SAL_CALL PresenterWindowManager::focusLost (const css::awt::FocusEvent& rEvent)
523 throw (css::uno::RuntimeException)
524 {
525 ThrowIfDisposed();
526 (void)rEvent;
527 }
528
529
530
531
532 //----- XEventListener --------------------------------------------------------
533
disposing(const lang::EventObject & rEvent)534 void SAL_CALL PresenterWindowManager::disposing (const lang::EventObject& rEvent)
535 throw (RuntimeException)
536 {
537 if (rEvent.Source == mxParentWindow)
538 mxParentWindow = NULL;
539 else
540 {
541 Reference<awt::XWindow> xWindow (rEvent.Source, UNO_QUERY);
542 }
543 }
544
545
546
547
548 //-----------------------------------------------------------------------------
549
PaintChildren(const awt::PaintEvent & rEvent) const550 bool PresenterWindowManager::PaintChildren (const awt::PaintEvent& rEvent) const
551 {
552 bool bChildInvalidated (false);
553
554 // Call windowPaint on all children that lie in or touch the
555 // update rectangle.
556 PresenterPaneContainer::PaneList::const_iterator iPane;
557 PresenterPaneContainer::PaneList::const_iterator iEnd (mpPaneContainer->maPanes.end());
558 for (iPane=mpPaneContainer->maPanes.begin(); iPane!=iEnd; ++iPane)
559 {
560 try
561 {
562 // Make sure that the pane shall and can be painted.
563 if ( ! (*iPane)->mbIsActive)
564 continue;
565 if ((*iPane)->mbIsSprite)
566 continue;
567 if ( ! (*iPane)->mxPane.is())
568 continue;
569 if ( ! (*iPane)->mxBorderWindow.is())
570 continue;
571 Reference<awt::XWindow> xBorderWindow ((*iPane)->mxBorderWindow);
572 if ( ! xBorderWindow.is())
573 continue;
574
575 // Get the area in which the border of the pane has to be painted.
576 const awt::Rectangle aBorderBox (xBorderWindow->getPosSize());
577 const awt::Rectangle aBorderUpdateBox(
578 PresenterGeometryHelper::Intersection(
579 rEvent.UpdateRect,
580 aBorderBox));
581 if (aBorderUpdateBox.Width<=0 || aBorderUpdateBox.Height<=0)
582 continue;
583
584 const awt::Rectangle aLocalBorderUpdateBox(
585 PresenterGeometryHelper::TranslateRectangle(
586 aBorderUpdateBox,
587 -aBorderBox.X,
588 -aBorderBox.Y));
589
590 // Invalidate the area of the content window.
591 mpPresenterController->GetPaintManager()->Invalidate(
592 xBorderWindow,
593 aLocalBorderUpdateBox,
594 sal_Int16(awt::InvalidateStyle::CHILDREN
595 | awt::InvalidateStyle::NOTRANSPARENT));
596 }
597 catch (RuntimeException&)
598 {
599 OSL_ASSERT(sal_False);
600 }
601 }
602
603 return bChildInvalidated;
604 }
605
606
607
608
SetLayoutMode(const LayoutMode eMode)609 void PresenterWindowManager::SetLayoutMode (const LayoutMode eMode)
610 {
611 OSL_ASSERT(mpPresenterController.get() != NULL);
612
613 if (meLayoutMode != eMode
614 || mbIsSlideSorterActive
615 || mbIsHelpViewActive)
616 {
617 meLayoutMode = eMode;
618 mbIsSlideSorterActive = false;
619 mbIsHelpViewActive = false;
620
621 mpPresenterController->RequestViews(
622 mbIsSlideSorterActive,
623 meLayoutMode==LM_Notes,
624 mbIsHelpViewActive);
625 Layout();
626 NotifyLayoutModeChange();
627 }
628 }
629
630
631
632
GetLayoutMode(void) const633 PresenterWindowManager::LayoutMode PresenterWindowManager::GetLayoutMode (void) const
634 {
635 return meLayoutMode;
636 }
637
638
639
640
SetSlideSorterState(bool bIsActive)641 void PresenterWindowManager::SetSlideSorterState (bool bIsActive)
642 {
643 if (mbIsSlideSorterActive != bIsActive)
644 {
645 mbIsSlideSorterActive = bIsActive;
646 if (mbIsSlideSorterActive)
647 mbIsHelpViewActive = false;
648 StoreViewMode(GetViewMode());
649
650 mpPresenterController->RequestViews(
651 mbIsSlideSorterActive,
652 meLayoutMode==LM_Notes,
653 mbIsHelpViewActive);
654 Layout();
655 NotifyLayoutModeChange();
656 }
657 }
658
659
660
661
IsSlideSorterActive(void) const662 bool PresenterWindowManager::IsSlideSorterActive (void) const
663 {
664 return mbIsSlideSorterActive;
665 }
666
667
668
669
SetHelpViewState(bool bIsActive)670 void PresenterWindowManager::SetHelpViewState (bool bIsActive)
671 {
672 if (mbIsHelpViewActive != bIsActive)
673 {
674 mbIsHelpViewActive = bIsActive;
675 if (mbIsHelpViewActive)
676 mbIsSlideSorterActive = false;
677 StoreViewMode(GetViewMode());
678
679 mpPresenterController->RequestViews(
680 mbIsSlideSorterActive,
681 meLayoutMode==LM_Notes,
682 mbIsHelpViewActive);
683 Layout();
684 NotifyLayoutModeChange();
685 }
686 }
687
688
689
690
IsHelpViewActive(void) const691 bool PresenterWindowManager::IsHelpViewActive (void) const
692 {
693 return mbIsHelpViewActive;
694 }
695
696
697
698
SetViewMode(const ViewMode eMode)699 void PresenterWindowManager::SetViewMode (const ViewMode eMode)
700 {
701 switch (eMode)
702 {
703 case VM_Standard:
704 SetSlideSorterState(false);
705 SetHelpViewState(false);
706 SetLayoutMode(LM_Standard);
707 break;
708
709 case VM_Notes:
710 SetSlideSorterState(false);
711 SetHelpViewState(false);
712 SetLayoutMode(LM_Notes);
713 break;
714
715 case VM_SlideOverview:
716 SetHelpViewState(false);
717 SetSlideSorterState(true);
718 break;
719
720 case VM_Help:
721 SetHelpViewState(true);
722 SetSlideSorterState(false);
723 break;
724 }
725
726 StoreViewMode(eMode);
727 }
728
729
730
731
GetViewMode(void) const732 PresenterWindowManager::ViewMode PresenterWindowManager::GetViewMode (void) const
733 {
734 if (mbIsHelpViewActive)
735 return VM_Help;
736 else if (mbIsSlideSorterActive)
737 return VM_SlideOverview;
738 else if (meLayoutMode == LM_Notes)
739 return VM_Notes;
740 else
741 return VM_Standard;
742 }
743
744
745
746
RestoreViewMode(void)747 void PresenterWindowManager::RestoreViewMode (void)
748 {
749 sal_Int32 nMode (0);
750 PresenterConfigurationAccess aConfiguration (
751 mxComponentContext,
752 OUString::createFromAscii("/org.openoffice.Office.PresenterScreen/"),
753 PresenterConfigurationAccess::READ_ONLY);
754 aConfiguration.GetConfigurationNode(A2S("Presenter/InitialViewMode")) >>= nMode;
755 switch (nMode)
756 {
757 default:
758 case 0:
759 SetViewMode(VM_Standard);
760 break;
761
762 case 1:
763 SetViewMode(VM_Notes);
764 break;
765
766 case 2:
767 SetViewMode(VM_SlideOverview);
768 break;
769 }
770 }
771
772
773
774
StoreViewMode(const ViewMode eViewMode)775 void PresenterWindowManager::StoreViewMode (const ViewMode eViewMode)
776 {
777 try
778 {
779 PresenterConfigurationAccess aConfiguration (
780 mxComponentContext,
781 OUString::createFromAscii("/org.openoffice.Office.PresenterScreen/"),
782 PresenterConfigurationAccess::READ_WRITE);
783 aConfiguration.GoToChild(A2S("Presenter"));
784 Any aValue;
785 switch (eViewMode)
786 {
787 default:
788 case VM_Standard:
789 aValue = Any(sal_Int32(0));
790 break;
791
792 case VM_Notes:
793 aValue = Any(sal_Int32(1));
794 break;
795
796 case VM_SlideOverview:
797 aValue = Any(sal_Int32(2));
798 break;
799 }
800
801 aConfiguration.SetProperty (A2S("InitialViewMode"), aValue);
802 aConfiguration.CommitChanges();
803 }
804 catch (Exception&)
805 {
806 }
807 }
808
809
810
811
AddLayoutListener(const Reference<document::XEventListener> & rxListener)812 void PresenterWindowManager::AddLayoutListener (
813 const Reference<document::XEventListener>& rxListener)
814 {
815 maLayoutListeners.push_back(rxListener);
816 }
817
818
819
820
RemoveLayoutListener(const Reference<document::XEventListener> & rxListener)821 void PresenterWindowManager::RemoveLayoutListener (
822 const Reference<document::XEventListener>& rxListener)
823 {
824 LayoutListenerContainer::iterator iListener (maLayoutListeners.begin());
825 LayoutListenerContainer::iterator iEnd (maLayoutListeners.end());
826 for ( ; iListener!=iEnd; ++iListener)
827 {
828 if (*iListener == rxListener)
829 {
830 maLayoutListeners.erase(iListener);
831 // Assume that there are no multiple entries.
832 break;
833 }
834 }
835 }
836
837
838
839
Layout(void)840 void PresenterWindowManager::Layout (void)
841 {
842 if (mxParentWindow.is() && ! mbIsLayouting)
843 {
844 mbIsLayoutPending = false;
845 mbIsLayouting = true;
846 mxScaledBackgroundBitmap = NULL;
847 mxClipPolygon = NULL;
848
849 try
850 {
851 if (mbIsSlideSorterActive)
852 LayoutSlideSorterMode();
853 else if (mbIsHelpViewActive)
854 LayoutHelpMode();
855 else
856 switch (meLayoutMode)
857 {
858 case LM_Standard:
859 default:
860 LayoutStandardMode();
861 break;
862
863 case LM_Notes:
864 LayoutNotesMode();
865 break;
866 }
867 }
868 catch (Exception&)
869 {
870 OSL_ASSERT(false);
871 throw;
872 }
873
874 mbIsLayouting = false;
875 }
876 }
877
878
879
880
LayoutStandardMode(void)881 void PresenterWindowManager::LayoutStandardMode (void)
882 {
883 awt::Rectangle aBox = mxParentWindow->getPosSize();
884
885 const double nGoldenRatio ((1 + sqrt(5.0)) / 2);
886 const double nGap (20);
887 const double nHorizontalSlideDivide (aBox.Width / nGoldenRatio);
888 double nSlidePreviewTop (0);
889
890 // For the current slide view calculate the outer height from the outer
891 // width. This takes into acount the slide aspect ratio and thus has to
892 // go over the inner pane size.
893 PresenterPaneContainer::SharedPaneDescriptor pPane (
894 mpPaneContainer->FindPaneURL(PresenterPaneFactory::msCurrentSlidePreviewPaneURL));
895 if (pPane.get() != NULL)
896 {
897 const awt::Size aCurrentSlideOuterBox(CalculatePaneSize(
898 nHorizontalSlideDivide - 1.5*nGap,
899 PresenterPaneFactory::msCurrentSlidePreviewPaneURL));
900 nSlidePreviewTop = (aBox.Height - aCurrentSlideOuterBox.Height) / 2;
901 SetPanePosSizeAbsolute (
902 PresenterPaneFactory::msCurrentSlidePreviewPaneURL,
903 nGap,
904 nSlidePreviewTop,
905 aCurrentSlideOuterBox.Width,
906 aCurrentSlideOuterBox.Height);
907 }
908
909
910 // For the next slide view calculate the outer height from the outer
911 // width. This takes into acount the slide aspect ratio and thus has to
912 // go over the inner pane size.
913 pPane = mpPaneContainer->FindPaneURL(PresenterPaneFactory::msNextSlidePreviewPaneURL);
914 if (pPane.get() != NULL)
915 {
916 const awt::Size aNextSlideOuterBox (CalculatePaneSize(
917 aBox.Width - nHorizontalSlideDivide - 1.5*nGap,
918 PresenterPaneFactory::msNextSlidePreviewPaneURL));
919 SetPanePosSizeAbsolute (
920 PresenterPaneFactory::msNextSlidePreviewPaneURL,
921 aBox.Width - aNextSlideOuterBox.Width - nGap,
922 nSlidePreviewTop,
923 aNextSlideOuterBox.Width,
924 aNextSlideOuterBox.Height);
925 }
926
927 LayoutToolBar();
928 }
929
930
931
932
LayoutNotesMode(void)933 void PresenterWindowManager::LayoutNotesMode (void)
934 {
935 awt::Rectangle aBox = mxParentWindow->getPosSize();
936
937 const geometry::RealRectangle2D aToolBarBox (LayoutToolBar());
938
939 const double nGoldenRatio ((1 + sqrt(5.0)) / 2);
940 const double nGap (20);
941 const double nPrimaryWidth (aBox.Width / nGoldenRatio);
942 const double nSecondaryWidth (aBox.Width - nPrimaryWidth);
943 const double nTertiaryWidth (nSecondaryWidth / nGoldenRatio);
944 double nSlidePreviewTop (0);
945 double nNotesViewBottom (aToolBarBox.Y1 - nGap);
946
947 // The notes view has no fixed aspect ratio.
948 PresenterPaneContainer::SharedPaneDescriptor pPane (
949 mpPaneContainer->FindPaneURL(PresenterPaneFactory::msNotesPaneURL));
950 if (pPane.get() != NULL)
951 {
952 const geometry::RealSize2D aNotesViewOuterSize(
953 nPrimaryWidth - 1.5*nGap + 0.5,
954 nNotesViewBottom);
955 nSlidePreviewTop = (aBox.Height
956 - aToolBarBox.Y2 + aToolBarBox.Y1 - aNotesViewOuterSize.Height) / 2;
957 SetPanePosSizeAbsolute (
958 PresenterPaneFactory::msNotesPaneURL,
959 aBox.Width - aNotesViewOuterSize.Width - nGap,
960 nSlidePreviewTop,
961 aNotesViewOuterSize.Width,
962 aNotesViewOuterSize.Height);
963 nNotesViewBottom = nSlidePreviewTop + aNotesViewOuterSize.Height;
964 }
965
966 // For the current slide view calculate the outer height from the outer
967 // width. This takes into acount the slide aspect ratio and thus has to
968 // go over the inner pane size.
969 pPane = mpPaneContainer->FindPaneURL(PresenterPaneFactory::msCurrentSlidePreviewPaneURL);
970 if (pPane.get() != NULL)
971 {
972 const awt::Size aCurrentSlideOuterBox(CalculatePaneSize(
973 nSecondaryWidth - 1.5*nGap,
974 PresenterPaneFactory::msCurrentSlidePreviewPaneURL));
975 SetPanePosSizeAbsolute (
976 PresenterPaneFactory::msCurrentSlidePreviewPaneURL,
977 nGap,
978 nSlidePreviewTop,
979 aCurrentSlideOuterBox.Width,
980 aCurrentSlideOuterBox.Height);
981 }
982
983
984 // For the next slide view calculate the outer height from the outer
985 // width. This takes into acount the slide aspect ratio and thus has to
986 // go over the inner pane size.
987 pPane = mpPaneContainer->FindPaneURL(PresenterPaneFactory::msNextSlidePreviewPaneURL);
988 if (pPane.get() != NULL)
989 {
990 const awt::Size aNextSlideOuterBox (CalculatePaneSize(
991 nTertiaryWidth,
992 PresenterPaneFactory::msNextSlidePreviewPaneURL));
993 SetPanePosSizeAbsolute (
994 PresenterPaneFactory::msNextSlidePreviewPaneURL,
995 nGap,
996 nNotesViewBottom - aNextSlideOuterBox.Height,
997 aNextSlideOuterBox.Width,
998 aNextSlideOuterBox.Height);
999 }
1000 }
1001
1002
1003
1004
LayoutSlideSorterMode(void)1005 void PresenterWindowManager::LayoutSlideSorterMode (void)
1006 {
1007 const geometry::RealRectangle2D aToolBarBox (LayoutToolBar());
1008
1009 awt::Rectangle aWindowBox = mxParentWindow->getPosSize();
1010 const double nGap (20);
1011 SetPanePosSizeAbsolute(
1012 mpPaneContainer->GetPaneURLForViewURL(PresenterViewFactory::msSlideSorterURL),
1013 nGap,
1014 nGap,
1015 aWindowBox.Width - 2*nGap,
1016 aToolBarBox.Y1 - 2*nGap);
1017 }
1018
1019
1020
1021
LayoutHelpMode(void)1022 void PresenterWindowManager::LayoutHelpMode (void)
1023 {
1024 const geometry::RealRectangle2D aToolBarBox (LayoutToolBar());
1025
1026 awt::Rectangle aWindowBox = mxParentWindow->getPosSize();
1027 const double nGap (20);
1028 const double nGoldenRatio ((1 + sqrt(5.0)) / 2);
1029 const double nWidth = ::std::min(aWindowBox.Width - 2*nGap, aWindowBox.Width/nGoldenRatio);
1030 SetPanePosSizeAbsolute(
1031 mpPaneContainer->GetPaneURLForViewURL(PresenterViewFactory::msHelpViewURL),
1032 (aWindowBox.Width - nWidth)/2,
1033 nGap,
1034 nWidth,
1035 aToolBarBox.Y1 - 2*nGap);
1036 }
1037
1038
1039
1040
LayoutToolBar(void)1041 geometry::RealRectangle2D PresenterWindowManager::LayoutToolBar (void)
1042 {
1043 double nToolBarWidth (400);
1044 double nToolBarHeight (80);
1045
1046 // Get access to the tool bar.
1047 PresenterPaneContainer::SharedPaneDescriptor pDescriptor(
1048 mpPaneContainer->FindPaneURL(PresenterPaneFactory::msToolBarPaneURL));
1049 if (pDescriptor.get() != NULL)
1050 {
1051 PresenterToolBarView* pToolBarView
1052 = dynamic_cast<PresenterToolBarView*>(pDescriptor->mxView.get());
1053 if (pToolBarView != NULL && pToolBarView->GetPresenterToolBar().is())
1054 {
1055 geometry::RealSize2D aSize (pToolBarView->GetPresenterToolBar()->GetMinimalSize());
1056
1057 if (mpPaneBorderPainter.is())
1058 {
1059 const awt::Rectangle aBox (mpPaneBorderPainter->addBorder (
1060 PresenterPaneFactory::msToolBarPaneURL,
1061 awt::Rectangle(
1062 0,
1063 0,
1064 PresenterGeometryHelper::Round(aSize.Width),
1065 PresenterGeometryHelper::Round(aSize.Height)),
1066 css::drawing::framework::BorderType_TOTAL_BORDER));
1067
1068 nToolBarWidth = aBox.Width;
1069 nToolBarHeight = aBox.Height;
1070 }
1071 else
1072 {
1073 nToolBarWidth = aSize.Width + 20;
1074 nToolBarHeight = aSize.Height + 10;
1075 }
1076 }
1077 }
1078
1079 const awt::Rectangle aBox = mxParentWindow->getPosSize();
1080 const double nToolBarX ((aBox.Width - nToolBarWidth) / 2);
1081 const double nToolBarY (aBox.Height - nToolBarHeight);
1082 SetPanePosSizeAbsolute(
1083 PresenterPaneFactory::msToolBarPaneURL,
1084 nToolBarX,
1085 nToolBarY,
1086 nToolBarWidth,
1087 nToolBarHeight);
1088
1089 return geometry::RealRectangle2D(
1090 nToolBarX,
1091 nToolBarY,
1092 nToolBarX + nToolBarWidth - 1,
1093 nToolBarY + nToolBarHeight - 1);
1094 }
1095
1096
1097
1098
CalculatePaneSize(const double nOuterWidth,const OUString & rsPaneURL)1099 awt::Size PresenterWindowManager::CalculatePaneSize (
1100 const double nOuterWidth,
1101 const OUString& rsPaneURL)
1102 {
1103 // Calculate the inner width by removing the pane border.
1104 awt::Rectangle aInnerBox (mpPaneBorderPainter->RemoveBorder (
1105 rsPaneURL,
1106 awt::Rectangle(0,0,
1107 sal_Int32(nOuterWidth+0.5),sal_Int32(nOuterWidth)),
1108 drawing::framework::BorderType_TOTAL_BORDER));
1109
1110 // Calculate the inner height with the help of the slide aspect ratio.
1111 const double nCurrentSlideInnerHeight (
1112 aInnerBox.Width / mpPresenterController->GetSlideAspectRatio());
1113
1114 // Add the pane border to get the outer box.
1115 awt::Rectangle aOuterBox (mpPaneBorderPainter->AddBorder (
1116 rsPaneURL,
1117 awt::Rectangle(0,0,
1118 aInnerBox.Width,sal_Int32(nCurrentSlideInnerHeight+0.5)),
1119 drawing::framework::BorderType_TOTAL_BORDER));
1120
1121 return awt::Size(aOuterBox.Width, aOuterBox.Height);
1122 }
1123
1124
1125
1126
NotifyLayoutModeChange(void)1127 void PresenterWindowManager::NotifyLayoutModeChange (void)
1128 {
1129 document::EventObject aEvent;
1130 aEvent.Source = Reference<XInterface>(static_cast<XWeak*>(this));
1131
1132 LayoutListenerContainer aContainerCopy (maLayoutListeners);
1133 LayoutListenerContainer::iterator iListener (aContainerCopy.begin());
1134 LayoutListenerContainer::iterator iEnd (aContainerCopy.end());
1135 for ( ; iListener!=iEnd; ++iListener)
1136 {
1137 if (iListener->is())
1138 {
1139 try
1140 {
1141 (*iListener)->notifyEvent(aEvent);
1142 }
1143 catch (lang::DisposedException&)
1144 {
1145 RemoveLayoutListener(*iListener);
1146 }
1147 catch (RuntimeException&)
1148 {
1149 }
1150 }
1151 }
1152 }
1153
1154
1155
1156
NotifyDisposing(void)1157 void PresenterWindowManager::NotifyDisposing (void)
1158 {
1159 lang::EventObject aEvent;
1160 aEvent.Source = static_cast<XWeak*>(this);
1161
1162 LayoutListenerContainer aContainer;
1163 aContainer.swap(maLayoutListeners);
1164 LayoutListenerContainer::iterator iListener (aContainer.begin());
1165 LayoutListenerContainer::iterator iEnd (aContainer.end());
1166 for ( ; iListener!=iEnd; ++iListener)
1167 {
1168 if (iListener->is())
1169 {
1170 try
1171 {
1172 (*iListener)->disposing(aEvent);
1173 }
1174 catch (lang::DisposedException&)
1175 {
1176 }
1177 catch (RuntimeException&)
1178 {
1179 }
1180 }
1181 }
1182 }
1183
1184
1185
1186
LayoutUnknownMode(void)1187 void PresenterWindowManager::LayoutUnknownMode (void)
1188 {
1189 awt::Rectangle aBox = mxParentWindow->getPosSize();
1190
1191 PresenterPaneContainer::PaneList::const_iterator iPane;
1192 PresenterPaneContainer::PaneList::const_iterator iEnd (mpPaneContainer->maPanes.end());
1193 for (iPane=mpPaneContainer->maPanes.begin(); iPane!=iEnd; ++iPane)
1194 {
1195 const PresenterPaneContainer::SharedPaneDescriptor& pDescriptor (*iPane);
1196 if ( ! pDescriptor->mxBorderWindow.is())
1197 continue;
1198
1199 // Layout the border window.
1200 const sal_Int32 nX = (sal_Int32)(pDescriptor->mnLeft * aBox.Width);
1201 const sal_Int32 nY = (sal_Int32)(pDescriptor->mnTop * aBox.Height);
1202 const sal_Int32 nWidth = (sal_Int32)(pDescriptor->mnRight * aBox.Width) - nX;
1203 const sal_Int32 nHeight = (sal_Int32)(pDescriptor->mnBottom * aBox.Height) - nY;
1204
1205 pDescriptor->mxBorderWindow->setPosSize(
1206 nX,nY,nWidth,nHeight,
1207 awt::PosSize::POSSIZE);
1208 }
1209 }
1210
1211
1212
1213
UpdateWindowSize(const Reference<awt::XWindow> & rxBorderWindow)1214 void PresenterWindowManager::UpdateWindowSize (const Reference<awt::XWindow>& rxBorderWindow)
1215 {
1216 PresenterPaneContainer::SharedPaneDescriptor pDescriptor (
1217 mpPaneContainer->FindBorderWindow(rxBorderWindow));
1218 if (pDescriptor.get() != NULL)
1219 {
1220 mxClipPolygon = NULL;
1221
1222 awt::Rectangle aParentBox = mxParentWindow->getPosSize();
1223 awt::Rectangle aBorderBox (pDescriptor->mxBorderWindow->getPosSize());
1224
1225 if ( ! mbIsLayouting)
1226 {
1227 const double nWidth (aParentBox.Width);
1228 const double nHeight (aParentBox.Height);
1229 pDescriptor->mnLeft = double(aBorderBox.X) / nWidth;
1230 pDescriptor->mnTop = double(aBorderBox.Y) / nHeight;
1231 pDescriptor->mnRight = double(aBorderBox.X + aBorderBox.Width) / nWidth;
1232 pDescriptor->mnBottom = double(aBorderBox.Y + aBorderBox.Height) / nHeight;
1233 }
1234 else
1235 {
1236 // This update of the window size was initiated by
1237 // Layout(). Therefore the window size does not have to be
1238 // updated.
1239 }
1240
1241 // ToTop is called last because it may invalidate the iterator.
1242 if ( ! mbIsLayouting)
1243 mpPaneContainer->ToTop(pDescriptor);
1244 }
1245 }
1246
1247
1248
1249
PaintBackground(const awt::Rectangle & rUpdateBox)1250 void PresenterWindowManager::PaintBackground (const awt::Rectangle& rUpdateBox)
1251 {
1252 (void)rUpdateBox;
1253 if ( ! mxParentWindow.is())
1254 return;
1255
1256 Reference<rendering::XGraphicDevice> xDevice (mxParentCanvas->getDevice());
1257 if ( ! xDevice.is())
1258 return;
1259
1260 // Create a polygon for the background and for clipping.
1261 Reference<rendering::XPolyPolygon2D> xBackgroundPolygon (
1262 PresenterGeometryHelper::CreatePolygon(mxParentWindow->getPosSize(), xDevice));
1263 if ( ! mxClipPolygon.is())
1264 mxClipPolygon = CreateClipPolyPolygon();
1265
1266 // Create View- and RenderState structs.
1267 const rendering::ViewState aViewState(
1268 geometry::AffineMatrix2D(1,0,0, 0,1,0),
1269 PresenterGeometryHelper::CreatePolygon(rUpdateBox, xDevice));
1270 rendering::RenderState aRenderState (
1271 geometry::AffineMatrix2D(1,0,0, 0,1,0),
1272 mxClipPolygon,
1273 Sequence<double>(4),
1274 rendering::CompositeOperation::SOURCE);
1275
1276 // Paint the background.
1277 if (mpBackgroundBitmap.get() != NULL)
1278 {
1279 ProvideBackgroundBitmap();
1280
1281 if (mxScaledBackgroundBitmap.is())
1282 {
1283 Sequence<rendering::Texture> aTextures (1);
1284 const geometry::IntegerSize2D aBitmapSize(mxScaledBackgroundBitmap->getSize());
1285 aTextures[0] = rendering::Texture (
1286 geometry::AffineMatrix2D(
1287 aBitmapSize.Width,0,0,
1288 0,aBitmapSize.Height,0),
1289 1,
1290 0,
1291 mxScaledBackgroundBitmap,
1292 NULL,
1293 NULL,
1294 rendering::StrokeAttributes(),
1295 rendering::TexturingMode::REPEAT,
1296 rendering::TexturingMode::REPEAT);
1297
1298 mxParentCanvas->fillTexturedPolyPolygon(
1299 xBackgroundPolygon,
1300 aViewState,
1301 aRenderState,
1302 aTextures);
1303 }
1304 else
1305 {
1306 const util::Color aBackgroundColor (mpBackgroundBitmap->maReplacementColor);
1307 aRenderState.DeviceColor[0] = ((aBackgroundColor >> 16) & 0x0ff) / 255.0;
1308 aRenderState.DeviceColor[1] = ((aBackgroundColor >> 8) & 0x0ff) / 255.0;
1309 aRenderState.DeviceColor[2] = ((aBackgroundColor >> 0) & 0x0ff) / 255.0;
1310 aRenderState.DeviceColor[3] = ((aBackgroundColor >> 24) & 0x0ff) / 255.0;
1311 mxParentCanvas->fillPolyPolygon(
1312 xBackgroundPolygon,
1313 aViewState,
1314 aRenderState);
1315 }
1316 }
1317 }
1318
1319
1320
1321
ProvideBackgroundBitmap(void)1322 void PresenterWindowManager::ProvideBackgroundBitmap (void)
1323 {
1324 if ( ! mxScaledBackgroundBitmap.is())
1325 {
1326 Reference<rendering::XBitmap> xBitmap (mpBackgroundBitmap->GetNormalBitmap());
1327 if (xBitmap.is())
1328 {
1329 const bool bStretchVertical (mpBackgroundBitmap->meVerticalTexturingMode
1330 == PresenterBitmapDescriptor::Stretch);
1331 const bool bStretchHorizontal (mpBackgroundBitmap->meHorizontalTexturingMode
1332 == PresenterBitmapDescriptor::Stretch);
1333 if (bStretchHorizontal || bStretchVertical)
1334 {
1335 geometry::RealSize2D aSize;
1336 if (bStretchVertical)
1337 aSize.Height = mxParentWindow->getPosSize().Height;
1338 else
1339 aSize.Height = xBitmap->getSize().Height;
1340 if (bStretchHorizontal)
1341 aSize.Width = mxParentWindow->getPosSize().Width;
1342 else
1343 aSize.Width = xBitmap->getSize().Width;
1344 mxScaledBackgroundBitmap = xBitmap->getScaledBitmap(aSize, sal_False);
1345 }
1346 else
1347 {
1348 mxScaledBackgroundBitmap
1349 = Reference<rendering::XBitmap>(xBitmap, UNO_QUERY);
1350 }
1351 }
1352 }
1353 }
1354
1355
1356
1357
CreateClipPolyPolygon(void) const1358 Reference<rendering::XPolyPolygon2D> PresenterWindowManager::CreateClipPolyPolygon (void) const
1359 {
1360 // Create a clip polygon that includes the whole update area but has the
1361 // content windows as holes.
1362 const sal_Int32 nPaneCount (mpPaneContainer->maPanes.size());
1363 ::std::vector<awt::Rectangle> aRectangles;
1364 aRectangles.reserve(1+nPaneCount);
1365 aRectangles.push_back(mxParentWindow->getPosSize());
1366 PresenterPaneContainer::PaneList::const_iterator iPane;
1367 PresenterPaneContainer::PaneList::const_iterator iEnd (mpPaneContainer->maPanes.end());
1368 for (iPane=mpPaneContainer->maPanes.begin(); iPane!=iEnd; ++iPane)
1369 {
1370 PresenterPaneContainer::SharedPaneDescriptor pDescriptor (*iPane);
1371 if ( ! pDescriptor->mbIsActive)
1372 continue;
1373 if ( ! pDescriptor->mbIsOpaque)
1374 continue;
1375 if ( ! pDescriptor->mxBorderWindow.is() || ! pDescriptor->mxContentWindow.is())
1376 continue;
1377 Reference<awt::XWindow2> xWindow (pDescriptor->mxBorderWindow, UNO_QUERY);
1378 if (xWindow.is() && ! xWindow->isVisible())
1379 continue;
1380
1381 const awt::Rectangle aOuterBorderBox (pDescriptor->mxBorderWindow->getPosSize());
1382 awt::Rectangle aInnerBorderBox (pDescriptor->mxContentWindow->getPosSize());
1383 aInnerBorderBox.X += aOuterBorderBox.X;
1384 aInnerBorderBox.Y += aOuterBorderBox.Y;
1385 aRectangles.push_back(aInnerBorderBox);
1386 }
1387 Reference<rendering::XPolyPolygon2D> xPolyPolygon (
1388 PresenterGeometryHelper::CreatePolygon(
1389 aRectangles,
1390 mxParentCanvas->getDevice()));
1391 if (xPolyPolygon.is())
1392 xPolyPolygon->setFillRule(rendering::FillRule_EVEN_ODD);
1393 return xPolyPolygon;
1394 }
1395
1396
1397
1398
UpdateWindowList(void)1399 void PresenterWindowManager::UpdateWindowList (void)
1400 {
1401 #ifdef ENABLE_PANE_RESIZING
1402 try
1403 {
1404 OSL_ASSERT(mxComponentContext.is());
1405
1406 Reference<lang::XComponent> xComponent (mxPaneBorderManager, UNO_QUERY);
1407 if (xComponent.is())
1408 xComponent->dispose();
1409
1410 Reference<lang::XMultiComponentFactory> xFactory (mxComponentContext->getServiceManager());
1411 if (xFactory.is())
1412 {
1413 Sequence<Any> aArguments (1 + mpPaneContainer->maPanes.size()*2);
1414 sal_Int32 nIndex (0);
1415 aArguments[nIndex++] = Any(mxParentWindow);
1416 for (sal_uInt32 nPaneIndex=0; nPaneIndex<mpPaneContainer->maPanes.size(); ++nPaneIndex)
1417 {
1418 if ( ! mpPaneContainer->maPanes[nPaneIndex]->mbIsActive)
1419 continue;
1420
1421 const Reference<awt::XWindow> xBorderWindow (
1422 mpPaneContainer->maPanes[nPaneIndex]->mxBorderWindow);
1423 const Reference<awt::XWindow> xContentWindow (
1424 mpPaneContainer->maPanes[nPaneIndex]->mxContentWindow);
1425 const Reference<awt::XWindow2> xBorderWindow2(xBorderWindow, UNO_QUERY);
1426 if (xBorderWindow.is()
1427 && xContentWindow.is()
1428 && ( ! xBorderWindow2.is() || xBorderWindow2->isVisible()))
1429 {
1430 aArguments[nIndex++] = Any(xBorderWindow);
1431 aArguments[nIndex++] = Any(xContentWindow);
1432 }
1433 }
1434
1435 aArguments.realloc(nIndex);
1436 rtl::Reference<PresenterPaneBorderManager> pManager (
1437 new PresenterPaneBorderManager (
1438 mxComponentContext,
1439 mpPresenterController));
1440 pManager->initialize(aArguments);
1441 mxPaneBorderManager = Reference<XInterface>(static_cast<XWeak*>(pManager.get()));
1442 }
1443 }
1444 catch (RuntimeException&)
1445 {
1446 }
1447 #endif
1448 }
1449
1450
1451
1452
Invalidate(void)1453 void PresenterWindowManager::Invalidate (void)
1454 {
1455 mpPresenterController->GetPaintManager()->Invalidate(mxParentWindow);
1456 }
1457
1458
1459
1460
GetParentWindow(void) const1461 Reference<awt::XWindow> PresenterWindowManager::GetParentWindow (void) const
1462 {
1463 return mxParentWindow;
1464 }
1465
1466
1467
1468
GetParentCanvas(void) const1469 Reference<rendering::XCanvas> PresenterWindowManager::GetParentCanvas (void) const
1470 {
1471 return mxParentCanvas;
1472 }
1473
1474
1475
1476
Update(void)1477 void PresenterWindowManager::Update (void)
1478 {
1479 mxClipPolygon = NULL;
1480 mbIsLayoutPending = true;
1481
1482 UpdateWindowList();
1483 Invalidate();
1484 }
1485
1486
1487
1488
ThrowIfDisposed(void) const1489 void PresenterWindowManager::ThrowIfDisposed (void) const
1490 throw (::com::sun::star::lang::DisposedException)
1491 {
1492 if (rBHelper.bDisposed || rBHelper.bInDispose)
1493 {
1494 throw lang::DisposedException (
1495 OUString(RTL_CONSTASCII_USTRINGPARAM(
1496 "PresenterWindowManager has already been disposed")),
1497 const_cast<uno::XWeak*>(static_cast<const uno::XWeak*>(this)));
1498 }
1499 }
1500
1501
1502
1503 namespace {
1504
1505 //===== ModeChangeAnimation ===================================================
1506
1507 class ModeChangeAnimation : public PresenterAnimation
1508 {
1509 public:
ModeChangeAnimation(const::boost::shared_ptr<PresenterSprite> & rpSprite,const Reference<rendering::XSpriteCanvas> & rxCanvas)1510 ModeChangeAnimation (
1511 const ::boost::shared_ptr<PresenterSprite>& rpSprite,
1512 const Reference<rendering::XSpriteCanvas>& rxCanvas)
1513 : PresenterAnimation (0, 1000, 20),
1514 mpSprite(rpSprite),
1515 mxCanvas(rxCanvas)
1516 {
1517 }
1518
Run(const double nProgress,const sal_uInt64 nCurrentTime)1519 virtual void Run (const double nProgress, const sal_uInt64 nCurrentTime)
1520 {
1521 (void)nCurrentTime;
1522 mpSprite->SetAlpha(1.0 - nProgress);
1523 mxCanvas->updateScreen(sal_False);
1524 }
1525
1526 private:
1527 ::boost::shared_ptr<PresenterSprite> mpSprite;
1528 Reference<rendering::XSpriteCanvas> mxCanvas;
1529 };
1530
1531
1532
1533
ModeChangeAnimationStarter(const Reference<drawing::framework::XConfigurationController> & rxConfigurationController,const Reference<awt::XWindow> & rxWindow,const Reference<rendering::XSpriteCanvas> & rxCanvas,const::boost::shared_ptr<PresenterAnimator> & rpAnimator)1534 ModeChangeAnimationStarter::ModeChangeAnimationStarter (
1535 const Reference<drawing::framework::XConfigurationController>& rxConfigurationController,
1536 const Reference<awt::XWindow>& rxWindow,
1537 const Reference<rendering::XSpriteCanvas>& rxCanvas,
1538 const ::boost::shared_ptr<PresenterAnimator>& rpAnimator)
1539 : ModeChangeAnimationStarterInterfaceBase(m_aMutex),
1540 mxConfigurationController(rxConfigurationController),
1541 mpAnimator(rpAnimator),
1542 mpSprite(new PresenterSprite()),
1543 mxCanvas(rxCanvas)
1544 {
1545 OSL_ASSERT(rxWindow.is());
1546 OSL_ASSERT(rxCanvas.is());
1547
1548 // Get the bitmap of the background.
1549 Reference<rendering::XBitmap> xBackgroundBitmap (rxCanvas, UNO_QUERY);
1550 if ( ! xBackgroundBitmap.is())
1551 return;
1552
1553 // Create the sprite.
1554 const awt::Rectangle aWindowSize (rxWindow->getPosSize());
1555 mpSprite->SetFactory(rxCanvas);
1556 mpSprite->Resize(geometry::RealSize2D(aWindowSize.Width, aWindowSize.Height));
1557 mpSprite->SetPriority(10);
1558
1559 // Fill it with the background inside the bounding box.
1560 const rendering::ViewState aViewState (
1561 geometry::AffineMatrix2D(1,0,0, 0,1,0),
1562 NULL);
1563 const rendering::RenderState aRenderState (
1564 geometry::AffineMatrix2D(1,0,0, 0,1,0),
1565 NULL,
1566 Sequence<double>(4),
1567 rendering::CompositeOperation::SOURCE);
1568 Reference<rendering::XCanvas> xSpriteCanvas (mpSprite->GetCanvas());
1569 if (xSpriteCanvas.is())
1570 {
1571 xSpriteCanvas->drawBitmap(xBackgroundBitmap, aViewState, aRenderState);
1572 mpSprite->Show();
1573 }
1574
1575 // Register as listener to be notified when the new panes are visible
1576 // and the sprite can be faded out.
1577 mxConfigurationController->addConfigurationChangeListener(
1578 this,
1579 A2S("ConfigurationUpdateEnd"),
1580 Any());
1581 }
1582
1583
1584
1585
~ModeChangeAnimationStarter(void)1586 ModeChangeAnimationStarter::~ModeChangeAnimationStarter (void)
1587 {
1588 }
1589
1590
1591
1592
disposing(void)1593 void SAL_CALL ModeChangeAnimationStarter::disposing (void)
1594 {
1595 mxConfigurationController = NULL;
1596 mpAnimator.reset();
1597 mpSprite.reset();
1598 }
1599
1600
1601
1602
1603 // XConfigurationChangeListener
1604
notifyConfigurationChange(const com::sun::star::drawing::framework::ConfigurationChangeEvent & rEvent)1605 void SAL_CALL ModeChangeAnimationStarter::notifyConfigurationChange (
1606 const com::sun::star::drawing::framework::ConfigurationChangeEvent& rEvent)
1607 throw (com::sun::star::uno::RuntimeException)
1608 {
1609 (void)rEvent;
1610
1611 // Start the actual animation.
1612 mpAnimator->AddAnimation(SharedPresenterAnimation(new ModeChangeAnimation(
1613 mpSprite,
1614 mxCanvas)));
1615
1616 mxConfigurationController->removeConfigurationChangeListener(this);
1617 }
1618
1619
1620
1621
1622 // XEventListener
1623
disposing(const com::sun::star::lang::EventObject & rEvent)1624 void SAL_CALL ModeChangeAnimationStarter::disposing (
1625 const com::sun::star::lang::EventObject& rEvent)
1626 throw (com::sun::star::uno::RuntimeException)
1627 {
1628 if (rEvent.Source == mxConfigurationController)
1629 mxConfigurationController = NULL;
1630 }
1631
1632
1633
1634 } // end of anonymous namespace
1635
1636
1637 } } // end of namespace ::sdext::presenter
1638