update dev300-m58
[ooovba.git] / sdext / source / presenter / PresenterWindowManager.cxx
blobc8ef855605ed597908bab4bbb70ab7995c363415
1 /*************************************************************************
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4 *
5 * Copyright 2008 by Sun Microsystems, Inc.
7 * OpenOffice.org - a multi-platform office productivity suite
9 * $RCSfile: PresenterWindowManager.cxx,v $
11 * $Revision: 1.7 $
13 * This file is part of OpenOffice.org.
15 * OpenOffice.org is free software: you can redistribute it and/or modify
16 * it under the terms of the GNU Lesser General Public License version 3
17 * only, as published by the Free Software Foundation.
19 * OpenOffice.org is distributed in the hope that it will be useful,
20 * but WITHOUT ANY WARRANTY; without even the implied warranty of
21 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
22 * GNU Lesser General Public License version 3 for more details
23 * (a copy is included in the LICENSE file that accompanied this code).
25 * You should have received a copy of the GNU Lesser General Public License
26 * version 3 along with OpenOffice.org. If not, see
27 * <http://www.openoffice.org/license.html>
28 * for a copy of the LGPLv3 License.
30 ************************************************************************/
32 // MARKER(update_precomp.py): autogen include statement, do not remove
33 #include "precompiled_sdext.hxx"
35 #include "PresenterWindowManager.hxx"
36 #include "PresenterAnimation.hxx"
37 #include "PresenterAnimator.hxx"
38 #include "PresenterController.hxx"
39 #include "PresenterGeometryHelper.hxx"
40 #include "PresenterHelper.hxx"
41 #include "PresenterPaintManager.hxx"
42 #include "PresenterPaneBase.hxx"
43 #include "PresenterPaneBorderManager.hxx"
44 #include "PresenterPaneBorderPainter.hxx"
45 #include "PresenterPaneContainer.hxx"
46 #include "PresenterPaneFactory.hxx"
47 #include "PresenterSprite.hxx"
48 #include "PresenterToolBar.hxx"
49 #include "PresenterViewFactory.hxx"
50 #include "PresenterTheme.hxx"
51 #include <com/sun/star/awt/InvalidateStyle.hpp>
52 #include <com/sun/star/awt/PosSize.hpp>
53 #include <com/sun/star/awt/SystemPointer.hpp>
54 #include <com/sun/star/awt/XDevice.hpp>
55 #include <com/sun/star/awt/XWindow2.hpp>
56 #include <com/sun/star/awt/XWindowPeer.hpp>
57 #include <com/sun/star/awt/WindowAttribute.hpp>
58 #include <com/sun/star/container/XChild.hpp>
59 #include <com/sun/star/drawing/framework/ResourceId.hpp>
60 #include <com/sun/star/rendering/CompositeOperation.hpp>
61 #include <com/sun/star/rendering/FillRule.hpp>
62 #include <com/sun/star/rendering/PathCapType.hpp>
63 #include <com/sun/star/rendering/PathJoinType.hpp>
64 #include <com/sun/star/rendering/Texture.hpp>
65 #include <com/sun/star/rendering/TexturingMode.hpp>
66 #include <com/sun/star/rendering/XSpriteCanvas.hpp>
67 #include <boost/bind.hpp>
68 #include <boost/bind/protect.hpp>
69 #include <math.h>
71 using namespace ::com::sun::star;
72 using namespace ::com::sun::star::uno;
73 using namespace ::com::sun::star::drawing::framework;
74 using ::rtl::OUString;
76 #undef ENABLE_PANE_RESIZING
78 #define A2S(pString) (::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(pString)))
80 namespace sdext { namespace presenter {
82 namespace {
84 typedef ::cppu::WeakComponentImplHelper1<
85 css::drawing::framework::XConfigurationChangeListener
86 > ModeChangeAnimationStarterInterfaceBase;
88 class ModeChangeAnimationStarter
89 : protected ::cppu::BaseMutex,
90 public ModeChangeAnimationStarterInterfaceBase
92 public:
93 ModeChangeAnimationStarter (
94 const Reference<drawing::framework::XConfigurationController>& rxConfigurationController,
95 const Reference<awt::XWindow>& rxWindow,
96 const Reference<rendering::XSpriteCanvas>& rxCanvas,
97 const ::boost::shared_ptr<PresenterAnimator>& rpAnimator);
98 virtual ~ModeChangeAnimationStarter (void);
99 virtual void SAL_CALL disposing (void);
101 // XConfigurationChangeListener
103 virtual void SAL_CALL notifyConfigurationChange (
104 const com::sun::star::drawing::framework::ConfigurationChangeEvent& rEvent)
105 throw (com::sun::star::uno::RuntimeException);
108 // XEventListener
110 virtual void SAL_CALL disposing (
111 const com::sun::star::lang::EventObject& rEvent)
112 throw (com::sun::star::uno::RuntimeException);
114 private:
115 Reference<drawing::framework::XConfigurationController> mxConfigurationController;
116 ::boost::shared_ptr<PresenterAnimator> mpAnimator;
117 ::boost::shared_ptr<PresenterSprite> mpSprite;
118 Reference<rendering::XSpriteCanvas> mxCanvas;
124 //===== PresenterWindowManager ================================================
126 PresenterWindowManager::PresenterWindowManager (
127 const Reference<XComponentContext>& rxContext,
128 const ::rtl::Reference<PresenterPaneContainer>& rpPaneContainer,
129 const ::rtl::Reference<PresenterController>& rpPresenterController)
130 : PresenterWindowManagerInterfaceBase(m_aMutex),
131 mxComponentContext(rxContext),
132 mpPresenterController(rpPresenterController),
133 mxParentWindow(),
134 mxParentCanvas(),
135 mxPaneBorderManager(),
136 mpPaneBorderPainter(),
137 mpPaneContainer(rpPaneContainer),
138 mbIsLayoutPending(true),
139 mbIsLayouting(false),
140 mpTheme(),
141 mpBackgroundBitmap(),
142 mxScaledBackgroundBitmap(),
143 maPaneBackgroundColor(),
144 mxClipPolygon(),
145 meLayoutMode(Generic),
146 mbIsSlideSorterActive(false),
147 mbIsHelpViewActive(false),
148 maLayoutListeners(),
149 mbIsMouseClickPending(false)
151 UpdateWindowList();
157 PresenterWindowManager::~PresenterWindowManager (void)
164 void SAL_CALL PresenterWindowManager::disposing (void)
166 NotifyDisposing();
168 SetParentPane(NULL);
170 Reference<lang::XComponent> xComponent (mxPaneBorderManager, UNO_QUERY);
171 if (xComponent.is())
172 xComponent->dispose();
173 mxPaneBorderManager = NULL;
175 PresenterPaneContainer::PaneList::const_iterator iPane;
176 PresenterPaneContainer::PaneList::const_iterator iEnd (mpPaneContainer->maPanes.end());
177 for (iPane=mpPaneContainer->maPanes.begin(); iPane!=iEnd; ++iPane)
179 if ((*iPane)->mxBorderWindow.is())
181 (*iPane)->mxBorderWindow->removeWindowListener(this);
182 (*iPane)->mxBorderWindow->removeFocusListener(this);
183 #ifndef ENABLE_PANE_RESIZING
184 (*iPane)->mxBorderWindow->removeMouseListener(this);
185 #endif
193 void PresenterWindowManager::SetParentPane (
194 const Reference<drawing::framework::XPane>& rxPane)
196 if (mxParentWindow.is())
198 mxParentWindow->removeWindowListener(this);
199 mxParentWindow->removePaintListener(this);
200 mxParentWindow->removeMouseListener(this);
201 mxParentWindow->removeFocusListener(this);
203 mxParentWindow = NULL;
204 mxParentCanvas = NULL;
206 if (rxPane.is())
208 mxParentWindow = rxPane->getWindow();
209 mxParentCanvas = rxPane->getCanvas();
211 else
213 mxParentWindow = NULL;
216 if (mxParentWindow.is())
218 mxParentWindow->addWindowListener(this);
219 mxParentWindow->addPaintListener(this);
220 mxParentWindow->addMouseListener(this);
221 mxParentWindow->addFocusListener(this);
223 // We paint our own background, make that of the parent window transparent.
224 Reference<awt::XWindowPeer> xPeer (mxParentWindow, UNO_QUERY);
225 if (xPeer.is())
226 xPeer->setBackground(util::Color(0xff000000));
233 void PresenterWindowManager::SetTheme (const ::boost::shared_ptr<PresenterTheme>& rpTheme)
235 mpTheme = rpTheme;
237 // Get background bitmap or background color from the theme.
239 if (mpTheme.get() != NULL)
241 mpBackgroundBitmap = mpTheme->GetBitmap(OUString(), A2S("Background"));
248 void PresenterWindowManager::NotifyPaneCreation (
249 const PresenterPaneContainer::SharedPaneDescriptor& rpDescriptor)
251 if (rpDescriptor.get()==NULL)
253 OSL_ASSERT(rpDescriptor.get()!=NULL);
254 return;
256 if ( ! rpDescriptor->mxContentWindow.is())
258 OSL_ASSERT(rpDescriptor->mxContentWindow.is());
259 return;
262 mbIsLayoutPending = true;
264 Reference<awt::XWindow> xBorderWindow (rpDescriptor->mxBorderWindow);
265 OSL_ASSERT(xBorderWindow.is());
266 if (xBorderWindow.is() && ! rpDescriptor->mbIsSprite)
268 Invalidate();
270 xBorderWindow->addWindowListener(this);
271 xBorderWindow->addFocusListener(this);
272 #ifndef ENABLE_PANE_RESIZING
273 xBorderWindow->addMouseListener(this);
274 #endif
277 UpdateWindowList();
278 Layout();
284 void PresenterWindowManager::NotifyViewCreation (const Reference<XView>& rxView)
286 PresenterPaneContainer::SharedPaneDescriptor pDescriptor (
287 mpPaneContainer->FindPaneId(rxView->getResourceId()->getAnchor()));
288 OSL_ASSERT(pDescriptor.get() != NULL);
289 if (pDescriptor.get() != NULL)
291 Layout();
293 mpPresenterController->GetPaintManager()->Invalidate(
294 pDescriptor->mxContentWindow,
295 (sal_Int16)(awt::InvalidateStyle::TRANSPARENT
296 | awt::InvalidateStyle::CHILDREN));
303 void PresenterWindowManager::SetPanePosSizeRelative (
304 const Reference<XResourceId>& rxPaneId,
305 const double nRelativeX,
306 const double nRelativeY,
307 const double nRelativeWidth,
308 const double nRelativeHeight)
310 PresenterPaneContainer::SharedPaneDescriptor pDescriptor (
311 mpPaneContainer->FindPaneId(rxPaneId));
312 if (pDescriptor.get() != NULL)
314 pDescriptor->mnLeft = nRelativeX;
315 pDescriptor->mnTop = nRelativeY;
316 pDescriptor->mnRight = nRelativeX + nRelativeWidth;
317 pDescriptor->mnBottom = nRelativeY + nRelativeHeight;
319 mpPaneContainer->ToTop(pDescriptor);
326 void PresenterWindowManager::SetPanePosSizeAbsolute (
327 const OUString& rsPaneURL,
328 const double nX,
329 const double nY,
330 const double nWidth,
331 const double nHeight)
333 PresenterPaneContainer::SharedPaneDescriptor pDescriptor (
334 mpPaneContainer->FindPaneURL(rsPaneURL));
335 if (pDescriptor.get() != NULL)
337 awt::Rectangle aParentBox = mxParentWindow->getPosSize();
338 if (aParentBox.Width > 0 && aParentBox.Height > 0)
340 pDescriptor->mnLeft = nX / aParentBox.Width;
341 pDescriptor->mnTop = nY / aParentBox.Height;
342 pDescriptor->mnRight = (nX + nWidth) / aParentBox.Width;
343 pDescriptor->mnBottom = (nY + nHeight) / aParentBox.Height;
345 if (pDescriptor->mxBorderWindow.is())
346 pDescriptor->mxBorderWindow->setPosSize(
347 ::sal::static_int_cast<sal_Int32>(nX),
348 ::sal::static_int_cast<sal_Int32>(nY),
349 ::sal::static_int_cast<sal_Int32>(nWidth),
350 ::sal::static_int_cast<sal_Int32>(nHeight),
351 awt::PosSize::POSSIZE);
358 void PresenterWindowManager::SetPaneBorderPainter (
359 const ::rtl::Reference<PresenterPaneBorderPainter>& rPainter)
361 mpPaneBorderPainter = rPainter;
367 //----- XWindowListener -------------------------------------------------------
369 void SAL_CALL PresenterWindowManager::windowResized (const awt::WindowEvent& rEvent)
370 throw (RuntimeException)
372 ThrowIfDisposed();
373 if (rEvent.Source == mxParentWindow)
375 Layout();
377 else
379 Reference<awt::XWindow> xWindow (rEvent.Source,UNO_QUERY);
380 if (xWindow.is())
382 UpdateWindowSize(xWindow);
384 // Make sure the background of a transparent window is painted.
385 mpPresenterController->GetPaintManager()->Invalidate(mxParentWindow);
393 void SAL_CALL PresenterWindowManager::windowMoved (const awt::WindowEvent& rEvent)
394 throw (RuntimeException)
396 ThrowIfDisposed();
397 if (rEvent.Source != mxParentWindow)
399 Reference<awt::XWindow> xWindow (rEvent.Source,UNO_QUERY);
400 UpdateWindowSize(xWindow);
402 // Make sure the background of a transparent window is painted.
403 mpPresenterController->GetPaintManager()->Invalidate(xWindow);
410 void SAL_CALL PresenterWindowManager::windowShown (const lang::EventObject& rEvent)
411 throw (RuntimeException)
413 (void)rEvent;
419 void SAL_CALL PresenterWindowManager::windowHidden (const lang::EventObject& rEvent)
420 throw (RuntimeException)
422 (void)rEvent;
428 //----- XPaintListener --------------------------------------------------------
430 void SAL_CALL PresenterWindowManager::windowPaint (const awt::PaintEvent& rEvent)
431 throw (RuntimeException)
433 ThrowIfDisposed();
435 if ( ! mxParentWindow.is())
436 return;
437 if ( ! mxParentCanvas.is())
438 return;
440 if (mpTheme.get()!=NULL)
444 if (mbIsLayoutPending)
445 Layout();
446 PaintBackground(rEvent.UpdateRect);
447 if ( ! PaintChildren(rEvent))
449 Reference<rendering::XSpriteCanvas> xSpriteCanvas (mxParentCanvas, UNO_QUERY);
450 // if (xSpriteCanvas.is())
451 // xSpriteCanvas->updateScreen(sal_False);
454 catch (RuntimeException&)
456 OSL_ASSERT(FALSE);
464 //----- XMouseListener --------------------------------------------------------
466 void SAL_CALL PresenterWindowManager::mousePressed (const css::awt::MouseEvent& rEvent)
467 throw(css::uno::RuntimeException)
469 (void)rEvent;
470 mbIsMouseClickPending = true;
476 void SAL_CALL PresenterWindowManager::mouseReleased (const css::awt::MouseEvent& rEvent)
477 throw(css::uno::RuntimeException)
479 #ifndef ENABLE_PANE_RESIZING
480 if (mbIsMouseClickPending)
482 mbIsMouseClickPending = false;
483 mpPresenterController->HandleMouseClick(rEvent);
485 #else
486 (void)rEvent;
487 #endif
493 void SAL_CALL PresenterWindowManager::mouseEntered (const css::awt::MouseEvent& rEvent)
494 throw(css::uno::RuntimeException)
496 (void)rEvent;
497 mbIsMouseClickPending = false;
503 void SAL_CALL PresenterWindowManager::mouseExited (const css::awt::MouseEvent& rEvent)
504 throw(css::uno::RuntimeException)
506 (void)rEvent;
507 mbIsMouseClickPending = false;
513 //----- XFocusListener --------------------------------------------------------
515 void SAL_CALL PresenterWindowManager::focusGained (const css::awt::FocusEvent& rEvent)
516 throw (css::uno::RuntimeException)
518 ThrowIfDisposed();
519 (void)rEvent;
525 void SAL_CALL PresenterWindowManager::focusLost (const css::awt::FocusEvent& rEvent)
526 throw (css::uno::RuntimeException)
528 ThrowIfDisposed();
529 (void)rEvent;
535 //----- XEventListener --------------------------------------------------------
537 void SAL_CALL PresenterWindowManager::disposing (const lang::EventObject& rEvent)
538 throw (RuntimeException)
540 if (rEvent.Source == mxParentWindow)
541 mxParentWindow = NULL;
542 else
544 Reference<awt::XWindow> xWindow (rEvent.Source, UNO_QUERY);
551 //-----------------------------------------------------------------------------
553 bool PresenterWindowManager::PaintChildren (const awt::PaintEvent& rEvent) const
555 bool bChildInvalidated (false);
557 // Call windowPaint on all children that lie in or touch the
558 // update rectangle.
559 PresenterPaneContainer::PaneList::const_iterator iPane;
560 PresenterPaneContainer::PaneList::const_iterator iEnd (mpPaneContainer->maPanes.end());
561 for (iPane=mpPaneContainer->maPanes.begin(); iPane!=iEnd; ++iPane)
565 // Make sure that the pane shall and can be painted.
566 if ( ! (*iPane)->mbIsActive)
567 continue;
568 if ((*iPane)->mbIsSprite)
569 continue;
570 if ( ! (*iPane)->mxPane.is())
571 continue;
572 if ( ! (*iPane)->mxBorderWindow.is())
573 continue;
574 Reference<awt::XWindow> xBorderWindow ((*iPane)->mxBorderWindow);
575 if ( ! xBorderWindow.is())
576 continue;
578 // Get the area in which the border of the pane has to be painted.
579 const awt::Rectangle aBorderBox (xBorderWindow->getPosSize());
580 const awt::Rectangle aBorderUpdateBox(
581 PresenterGeometryHelper::Intersection(
582 rEvent.UpdateRect,
583 aBorderBox));
584 if (aBorderUpdateBox.Width<=0 || aBorderUpdateBox.Height<=0)
585 continue;
587 const awt::Rectangle aLocalBorderUpdateBox(
588 PresenterGeometryHelper::TranslateRectangle(
589 aBorderUpdateBox,
590 -aBorderBox.X,
591 -aBorderBox.Y));
593 // Invalidate the area of the content window.
594 mpPresenterController->GetPaintManager()->Invalidate(
595 xBorderWindow,
596 aLocalBorderUpdateBox,
597 sal_Int16(awt::InvalidateStyle::CHILDREN
598 | awt::InvalidateStyle::NOTRANSPARENT));
600 catch (RuntimeException&)
602 OSL_ASSERT(FALSE);
606 return bChildInvalidated;
612 void PresenterWindowManager::SetLayoutMode (const LayoutMode eMode)
614 OSL_ASSERT(mpPresenterController.get() != NULL);
616 if (meLayoutMode != eMode
617 || mbIsSlideSorterActive
618 || mbIsHelpViewActive)
620 meLayoutMode = eMode;
621 mbIsSlideSorterActive = false;
622 mbIsHelpViewActive = false;
624 mpPresenterController->RequestViews(
625 mbIsSlideSorterActive,
626 meLayoutMode==Notes,
627 mbIsHelpViewActive);
628 Layout();
629 NotifyLayoutModeChange();
636 PresenterWindowManager::LayoutMode PresenterWindowManager::GetLayoutMode (void) const
638 return meLayoutMode;
644 void PresenterWindowManager::SetSlideSorterState (bool bIsActive)
646 if (mbIsSlideSorterActive != bIsActive)
648 mbIsSlideSorterActive = bIsActive;
649 if (mbIsSlideSorterActive)
650 mbIsHelpViewActive = false;
652 mpPresenterController->RequestViews(
653 mbIsSlideSorterActive,
654 meLayoutMode==Notes,
655 mbIsHelpViewActive);
656 Layout();
657 NotifyLayoutModeChange();
664 bool PresenterWindowManager::IsSlideSorterActive (void) const
666 return mbIsSlideSorterActive;
672 void PresenterWindowManager::SetHelpViewState (bool bIsActive)
674 if (mbIsHelpViewActive != bIsActive)
676 mbIsHelpViewActive = bIsActive;
677 if (mbIsHelpViewActive)
678 mbIsSlideSorterActive = false;
680 mpPresenterController->RequestViews(
681 mbIsSlideSorterActive,
682 meLayoutMode==Notes,
683 mbIsHelpViewActive);
684 Layout();
685 NotifyLayoutModeChange();
692 bool PresenterWindowManager::IsHelpViewActive (void) const
694 return mbIsHelpViewActive;
700 void PresenterWindowManager::AddLayoutListener (
701 const Reference<document::XEventListener>& rxListener)
703 maLayoutListeners.push_back(rxListener);
709 void PresenterWindowManager::RemoveLayoutListener (
710 const Reference<document::XEventListener>& rxListener)
712 LayoutListenerContainer::iterator iListener (maLayoutListeners.begin());
713 LayoutListenerContainer::iterator iEnd (maLayoutListeners.end());
714 for ( ; iListener!=iEnd; ++iListener)
716 if (*iListener == rxListener)
718 maLayoutListeners.erase(iListener);
719 // Assume that there are no multiple entries.
720 break;
728 void PresenterWindowManager::Layout (void)
730 if (mxParentWindow.is() && ! mbIsLayouting)
732 mbIsLayoutPending = false;
733 mbIsLayouting = true;
734 mxScaledBackgroundBitmap = NULL;
735 mxClipPolygon = NULL;
739 if (mbIsSlideSorterActive)
740 LayoutSlideSorterMode();
741 else if (mbIsHelpViewActive)
742 LayoutHelpMode();
743 else
744 switch (meLayoutMode)
746 case Standard:
747 default:
748 LayoutStandardMode();
749 break;
751 case Notes:
752 LayoutNotesMode();
753 break;
755 case Generic:
756 LayoutUnknownMode();
757 break;
760 catch (Exception&)
762 OSL_ASSERT(false);
763 throw;
766 mbIsLayouting = false;
773 void PresenterWindowManager::LayoutStandardMode (void)
775 awt::Rectangle aBox = mxParentWindow->getPosSize();
777 const double nGoldenRatio ((1 + sqrt(5.0)) / 2);
778 const double nGap (20);
779 const double nHorizontalSlideDivide (aBox.Width / nGoldenRatio);
780 double nSlidePreviewTop (0);
782 // For the current slide view calculate the outer height from the outer
783 // width. This takes into acount the slide aspect ratio and thus has to
784 // go over the inner pane size.
785 PresenterPaneContainer::SharedPaneDescriptor pPane (
786 mpPaneContainer->FindPaneURL(PresenterPaneFactory::msCurrentSlidePreviewPaneURL));
787 if (pPane.get() != NULL)
789 const awt::Size aCurrentSlideOuterBox(CalculatePaneSize(
790 nHorizontalSlideDivide - 1.5*nGap,
791 PresenterPaneFactory::msCurrentSlidePreviewPaneURL));
792 nSlidePreviewTop = (aBox.Height - aCurrentSlideOuterBox.Height) / 2;
793 SetPanePosSizeAbsolute (
794 PresenterPaneFactory::msCurrentSlidePreviewPaneURL,
795 nGap,
796 nSlidePreviewTop,
797 aCurrentSlideOuterBox.Width,
798 aCurrentSlideOuterBox.Height);
802 // For the next slide view calculate the outer height from the outer
803 // width. This takes into acount the slide aspect ratio and thus has to
804 // go over the inner pane size.
805 pPane = mpPaneContainer->FindPaneURL(PresenterPaneFactory::msNextSlidePreviewPaneURL);
806 if (pPane.get() != NULL)
808 const awt::Size aNextSlideOuterBox (CalculatePaneSize(
809 aBox.Width - nHorizontalSlideDivide - 1.5*nGap,
810 PresenterPaneFactory::msNextSlidePreviewPaneURL));
811 SetPanePosSizeAbsolute (
812 PresenterPaneFactory::msNextSlidePreviewPaneURL,
813 aBox.Width - aNextSlideOuterBox.Width - nGap,
814 nSlidePreviewTop,
815 aNextSlideOuterBox.Width,
816 aNextSlideOuterBox.Height);
819 LayoutToolBar();
825 void PresenterWindowManager::LayoutNotesMode (void)
827 awt::Rectangle aBox = mxParentWindow->getPosSize();
829 const geometry::RealRectangle2D aToolBarBox (LayoutToolBar());
831 const double nGoldenRatio ((1 + sqrt(5.0)) / 2);
832 const double nGap (20);
833 const double nPrimaryWidth (aBox.Width / nGoldenRatio);
834 const double nSecondaryWidth (aBox.Width - nPrimaryWidth);
835 const double nTertiaryWidth (nSecondaryWidth / nGoldenRatio);
836 double nSlidePreviewTop (0);
837 double nNotesViewBottom (aToolBarBox.Y1 - nGap);
839 // The notes view has no fixed aspect ratio.
840 PresenterPaneContainer::SharedPaneDescriptor pPane (
841 mpPaneContainer->FindPaneURL(PresenterPaneFactory::msNotesPaneURL));
842 if (pPane.get() != NULL)
844 const geometry::RealSize2D aNotesViewOuterSize(
845 nPrimaryWidth - 1.5*nGap + 0.5,
846 nNotesViewBottom);
847 nSlidePreviewTop = (aBox.Height
848 - aToolBarBox.Y2 + aToolBarBox.Y1 - aNotesViewOuterSize.Height) / 2;
849 SetPanePosSizeAbsolute (
850 PresenterPaneFactory::msNotesPaneURL,
851 aBox.Width - aNotesViewOuterSize.Width - nGap,
852 nSlidePreviewTop,
853 aNotesViewOuterSize.Width,
854 aNotesViewOuterSize.Height);
855 nNotesViewBottom = nSlidePreviewTop + aNotesViewOuterSize.Height;
858 // For the current slide view calculate the outer height from the outer
859 // width. This takes into acount the slide aspect ratio and thus has to
860 // go over the inner pane size.
861 pPane = mpPaneContainer->FindPaneURL(PresenterPaneFactory::msCurrentSlidePreviewPaneURL);
862 if (pPane.get() != NULL)
864 const awt::Size aCurrentSlideOuterBox(CalculatePaneSize(
865 nSecondaryWidth - 1.5*nGap,
866 PresenterPaneFactory::msCurrentSlidePreviewPaneURL));
867 SetPanePosSizeAbsolute (
868 PresenterPaneFactory::msCurrentSlidePreviewPaneURL,
869 nGap,
870 nSlidePreviewTop,
871 aCurrentSlideOuterBox.Width,
872 aCurrentSlideOuterBox.Height);
876 // For the next slide view calculate the outer height from the outer
877 // width. This takes into acount the slide aspect ratio and thus has to
878 // go over the inner pane size.
879 pPane = mpPaneContainer->FindPaneURL(PresenterPaneFactory::msNextSlidePreviewPaneURL);
880 if (pPane.get() != NULL)
882 const awt::Size aNextSlideOuterBox (CalculatePaneSize(
883 nTertiaryWidth,
884 PresenterPaneFactory::msNextSlidePreviewPaneURL));
885 SetPanePosSizeAbsolute (
886 PresenterPaneFactory::msNextSlidePreviewPaneURL,
887 nGap,
888 nNotesViewBottom - aNextSlideOuterBox.Height,
889 aNextSlideOuterBox.Width,
890 aNextSlideOuterBox.Height);
897 void PresenterWindowManager::LayoutSlideSorterMode (void)
899 const geometry::RealRectangle2D aToolBarBox (LayoutToolBar());
901 awt::Rectangle aWindowBox = mxParentWindow->getPosSize();
902 const double nGap (20);
903 SetPanePosSizeAbsolute(
904 mpPaneContainer->GetPaneURLForViewURL(PresenterViewFactory::msSlideSorterURL),
905 nGap,
906 nGap,
907 aWindowBox.Width - 2*nGap,
908 aToolBarBox.Y1 - 2*nGap);
914 void PresenterWindowManager::LayoutHelpMode (void)
916 const geometry::RealRectangle2D aToolBarBox (LayoutToolBar());
918 awt::Rectangle aWindowBox = mxParentWindow->getPosSize();
919 const double nGap (20);
920 const double nGoldenRatio ((1 + sqrt(5.0)) / 2);
921 const double nWidth = ::std::min(aWindowBox.Width - 2*nGap, aWindowBox.Width/nGoldenRatio);
922 SetPanePosSizeAbsolute(
923 mpPaneContainer->GetPaneURLForViewURL(PresenterViewFactory::msHelpViewURL),
924 (aWindowBox.Width - nWidth)/2,
925 nGap,
926 nWidth,
927 aToolBarBox.Y1 - 2*nGap);
933 geometry::RealRectangle2D PresenterWindowManager::LayoutToolBar (void)
935 double nToolBarWidth (400);
936 double nToolBarHeight (80);
938 // Get access to the tool bar.
939 PresenterPaneContainer::SharedPaneDescriptor pDescriptor(
940 mpPaneContainer->FindPaneURL(PresenterPaneFactory::msToolBarPaneURL));
941 if (pDescriptor.get() != NULL)
943 PresenterToolBarView* pToolBarView
944 = dynamic_cast<PresenterToolBarView*>(pDescriptor->mxView.get());
945 if (pToolBarView != NULL && pToolBarView->GetPresenterToolBar().is())
947 geometry::RealSize2D aSize (pToolBarView->GetPresenterToolBar()->GetMinimalSize());
949 if (mpPaneBorderPainter.is())
951 const awt::Rectangle aBox (mpPaneBorderPainter->addBorder (
952 PresenterPaneFactory::msToolBarPaneURL,
953 awt::Rectangle(
956 PresenterGeometryHelper::Round(aSize.Width),
957 PresenterGeometryHelper::Round(aSize.Height)),
958 css::drawing::framework::BorderType_TOTAL_BORDER));
960 nToolBarWidth = aBox.Width;
961 nToolBarHeight = aBox.Height;
963 else
965 nToolBarWidth = aSize.Width + 20;
966 nToolBarHeight = aSize.Height + 10;
971 const awt::Rectangle aBox = mxParentWindow->getPosSize();
972 const double nToolBarX ((aBox.Width - nToolBarWidth) / 2);
973 const double nToolBarY (aBox.Height - nToolBarHeight);
974 SetPanePosSizeAbsolute(
975 PresenterPaneFactory::msToolBarPaneURL,
976 nToolBarX,
977 nToolBarY,
978 nToolBarWidth,
979 nToolBarHeight);
981 return geometry::RealRectangle2D(
982 nToolBarX,
983 nToolBarY,
984 nToolBarX + nToolBarWidth - 1,
985 nToolBarY + nToolBarHeight - 1);
991 awt::Size PresenterWindowManager::CalculatePaneSize (
992 const double nOuterWidth,
993 const OUString& rsPaneURL)
995 // Calculate the inner width by removing the pane border.
996 awt::Rectangle aInnerBox (mpPaneBorderPainter->RemoveBorder (
997 rsPaneURL,
998 awt::Rectangle(0,0,
999 sal_Int32(nOuterWidth+0.5),sal_Int32(nOuterWidth)),
1000 drawing::framework::BorderType_TOTAL_BORDER));
1002 // Calculate the inner height with the help of the slide aspect ratio.
1003 const double nCurrentSlideInnerHeight (
1004 aInnerBox.Width / mpPresenterController->GetSlideAspectRatio());
1006 // Add the pane border to get the outer box.
1007 awt::Rectangle aOuterBox (mpPaneBorderPainter->AddBorder (
1008 rsPaneURL,
1009 awt::Rectangle(0,0,
1010 aInnerBox.Width,sal_Int32(nCurrentSlideInnerHeight+0.5)),
1011 drawing::framework::BorderType_TOTAL_BORDER));
1013 return awt::Size(aOuterBox.Width, aOuterBox.Height);
1019 void PresenterWindowManager::NotifyLayoutModeChange (void)
1021 document::EventObject aEvent;
1022 aEvent.Source = Reference<XInterface>(static_cast<XWeak*>(this));
1024 LayoutListenerContainer aContainerCopy (maLayoutListeners);
1025 LayoutListenerContainer::iterator iListener (aContainerCopy.begin());
1026 LayoutListenerContainer::iterator iEnd (aContainerCopy.end());
1027 for ( ; iListener!=iEnd; ++iListener)
1029 if (iListener->is())
1033 (*iListener)->notifyEvent(aEvent);
1035 catch (lang::DisposedException&)
1037 RemoveLayoutListener(*iListener);
1039 catch (RuntimeException&)
1049 void PresenterWindowManager::NotifyDisposing (void)
1051 lang::EventObject aEvent;
1052 aEvent.Source = static_cast<XWeak*>(this);
1054 LayoutListenerContainer aContainer;
1055 aContainer.swap(maLayoutListeners);
1056 LayoutListenerContainer::iterator iListener (aContainer.begin());
1057 LayoutListenerContainer::iterator iEnd (aContainer.end());
1058 for ( ; iListener!=iEnd; ++iListener)
1060 if (iListener->is())
1064 (*iListener)->disposing(aEvent);
1066 catch (lang::DisposedException&)
1069 catch (RuntimeException&)
1079 void PresenterWindowManager::LayoutUnknownMode (void)
1081 awt::Rectangle aBox = mxParentWindow->getPosSize();
1083 PresenterPaneContainer::PaneList::const_iterator iPane;
1084 PresenterPaneContainer::PaneList::const_iterator iEnd (mpPaneContainer->maPanes.end());
1085 for (iPane=mpPaneContainer->maPanes.begin(); iPane!=iEnd; ++iPane)
1087 const PresenterPaneContainer::SharedPaneDescriptor& pDescriptor (*iPane);
1088 if ( ! pDescriptor->mxBorderWindow.is())
1089 continue;
1091 // Layout the border window.
1092 const sal_Int32 nX = (sal_Int32)(pDescriptor->mnLeft * aBox.Width);
1093 const sal_Int32 nY = (sal_Int32)(pDescriptor->mnTop * aBox.Height);
1094 const sal_Int32 nWidth = (sal_Int32)(pDescriptor->mnRight * aBox.Width) - nX;
1095 const sal_Int32 nHeight = (sal_Int32)(pDescriptor->mnBottom * aBox.Height) - nY;
1097 pDescriptor->mxBorderWindow->setPosSize(
1098 nX,nY,nWidth,nHeight,
1099 awt::PosSize::POSSIZE);
1106 void PresenterWindowManager::UpdateWindowSize (const Reference<awt::XWindow>& rxBorderWindow)
1108 PresenterPaneContainer::SharedPaneDescriptor pDescriptor (
1109 mpPaneContainer->FindBorderWindow(rxBorderWindow));
1110 if (pDescriptor.get() != NULL)
1112 mxClipPolygon = NULL;
1114 awt::Rectangle aParentBox = mxParentWindow->getPosSize();
1115 awt::Rectangle aBorderBox (pDescriptor->mxBorderWindow->getPosSize());
1117 if ( ! mbIsLayouting)
1119 const double nWidth (aParentBox.Width);
1120 const double nHeight (aParentBox.Height);
1121 pDescriptor->mnLeft = double(aBorderBox.X) / nWidth;
1122 pDescriptor->mnTop = double(aBorderBox.Y) / nHeight;
1123 pDescriptor->mnRight = double(aBorderBox.X + aBorderBox.Width) / nWidth;
1124 pDescriptor->mnBottom = double(aBorderBox.Y + aBorderBox.Height) / nHeight;
1126 else
1128 // This update of the window size was initiated by
1129 // Layout(). Therefore the window size does not have to be
1130 // updated.
1133 // ToTop is called last because it may invalidate the iterator.
1134 if ( ! mbIsLayouting)
1135 mpPaneContainer->ToTop(pDescriptor);
1142 void PresenterWindowManager::PaintBackground (const awt::Rectangle& rUpdateBox)
1144 (void)rUpdateBox;
1145 if ( ! mxParentWindow.is())
1146 return;
1148 Reference<rendering::XGraphicDevice> xDevice (mxParentCanvas->getDevice());
1149 if ( ! xDevice.is())
1150 return;
1152 // Create a polygon for the background and for clipping.
1153 Reference<rendering::XPolyPolygon2D> xBackgroundPolygon (
1154 PresenterGeometryHelper::CreatePolygon(mxParentWindow->getPosSize(), xDevice));
1155 if ( ! mxClipPolygon.is())
1156 mxClipPolygon = CreateClipPolyPolygon();
1158 // Create View- and RenderState structs.
1159 const rendering::ViewState aViewState(
1160 geometry::AffineMatrix2D(1,0,0, 0,1,0),
1161 PresenterGeometryHelper::CreatePolygon(rUpdateBox, xDevice));
1162 rendering::RenderState aRenderState (
1163 geometry::AffineMatrix2D(1,0,0, 0,1,0),
1164 mxClipPolygon,
1165 Sequence<double>(4),
1166 rendering::CompositeOperation::SOURCE);
1168 // Paint the background.
1169 if (mpBackgroundBitmap.get() != NULL)
1171 ProvideBackgroundBitmap();
1173 if (mxScaledBackgroundBitmap.is())
1175 Sequence<rendering::Texture> aTextures (1);
1176 const geometry::IntegerSize2D aBitmapSize(mxScaledBackgroundBitmap->getSize());
1177 aTextures[0] = rendering::Texture (
1178 geometry::AffineMatrix2D(
1179 aBitmapSize.Width,0,0,
1180 0,aBitmapSize.Height,0),
1183 mxScaledBackgroundBitmap,
1184 NULL,
1185 NULL,
1186 rendering::StrokeAttributes(),
1187 rendering::TexturingMode::REPEAT,
1188 rendering::TexturingMode::REPEAT);
1190 mxParentCanvas->fillTexturedPolyPolygon(
1191 xBackgroundPolygon,
1192 aViewState,
1193 aRenderState,
1194 aTextures);
1196 else
1198 const util::Color aBackgroundColor (mpBackgroundBitmap->maReplacementColor);
1199 aRenderState.DeviceColor[0] = ((aBackgroundColor >> 16) & 0x0ff) / 255.0;
1200 aRenderState.DeviceColor[1] = ((aBackgroundColor >> 8) & 0x0ff) / 255.0;
1201 aRenderState.DeviceColor[2] = ((aBackgroundColor >> 0) & 0x0ff) / 255.0;
1202 aRenderState.DeviceColor[3] = ((aBackgroundColor >> 24) & 0x0ff) / 255.0;
1203 mxParentCanvas->fillPolyPolygon(
1204 xBackgroundPolygon,
1205 aViewState,
1206 aRenderState);
1214 void PresenterWindowManager::ProvideBackgroundBitmap (void)
1216 if ( ! mxScaledBackgroundBitmap.is())
1218 Reference<rendering::XBitmap> xBitmap (mpBackgroundBitmap->GetNormalBitmap());
1219 if (xBitmap.is())
1221 const bool bStretchVertical (mpBackgroundBitmap->meVerticalTexturingMode
1222 == PresenterBitmapDescriptor::Stretch);
1223 const bool bStretchHorizontal (mpBackgroundBitmap->meHorizontalTexturingMode
1224 == PresenterBitmapDescriptor::Stretch);
1225 if (bStretchHorizontal || bStretchVertical)
1227 geometry::RealSize2D aSize;
1228 if (bStretchVertical)
1229 aSize.Height = mxParentWindow->getPosSize().Height;
1230 else
1231 aSize.Height = xBitmap->getSize().Height;
1232 if (bStretchHorizontal)
1233 aSize.Width = mxParentWindow->getPosSize().Width;
1234 else
1235 aSize.Width = xBitmap->getSize().Width;
1236 mxScaledBackgroundBitmap = xBitmap->getScaledBitmap(aSize, sal_False);
1238 else
1240 mxScaledBackgroundBitmap
1241 = Reference<rendering::XBitmap>(xBitmap, UNO_QUERY);
1250 Reference<rendering::XPolyPolygon2D> PresenterWindowManager::CreateClipPolyPolygon (void) const
1252 // Create a clip polygon that includes the whole update area but has the
1253 // content windows as holes.
1254 const sal_Int32 nPaneCount (mpPaneContainer->maPanes.size());
1255 ::std::vector<awt::Rectangle> aRectangles;
1256 aRectangles.reserve(1+nPaneCount);
1257 aRectangles.push_back(mxParentWindow->getPosSize());
1258 PresenterPaneContainer::PaneList::const_iterator iPane;
1259 PresenterPaneContainer::PaneList::const_iterator iEnd (mpPaneContainer->maPanes.end());
1260 for (iPane=mpPaneContainer->maPanes.begin(); iPane!=iEnd; ++iPane)
1262 PresenterPaneContainer::SharedPaneDescriptor pDescriptor (*iPane);
1263 if ( ! pDescriptor->mbIsActive)
1264 continue;
1265 if ( ! pDescriptor->mbIsOpaque)
1266 continue;
1267 if ( ! pDescriptor->mxBorderWindow.is() || ! pDescriptor->mxContentWindow.is())
1268 continue;
1269 Reference<awt::XWindow2> xWindow (pDescriptor->mxBorderWindow, UNO_QUERY);
1270 if (xWindow.is() && ! xWindow->isVisible())
1271 continue;
1273 const awt::Rectangle aOuterBorderBox (pDescriptor->mxBorderWindow->getPosSize());
1274 awt::Rectangle aInnerBorderBox (pDescriptor->mxContentWindow->getPosSize());
1275 aInnerBorderBox.X += aOuterBorderBox.X;
1276 aInnerBorderBox.Y += aOuterBorderBox.Y;
1277 aRectangles.push_back(aInnerBorderBox);
1279 Reference<rendering::XPolyPolygon2D> xPolyPolygon (
1280 PresenterGeometryHelper::CreatePolygon(
1281 aRectangles,
1282 mxParentCanvas->getDevice()));
1283 if (xPolyPolygon.is())
1284 xPolyPolygon->setFillRule(rendering::FillRule_EVEN_ODD);
1285 return xPolyPolygon;
1291 void PresenterWindowManager::UpdateWindowList (void)
1293 #ifdef ENABLE_PANE_RESIZING
1296 OSL_ASSERT(mxComponentContext.is());
1298 Reference<lang::XComponent> xComponent (mxPaneBorderManager, UNO_QUERY);
1299 if (xComponent.is())
1300 xComponent->dispose();
1302 Reference<lang::XMultiComponentFactory> xFactory (mxComponentContext->getServiceManager());
1303 if (xFactory.is())
1305 Sequence<Any> aArguments (1 + mpPaneContainer->maPanes.size()*2);
1306 sal_Int32 nIndex (0);
1307 aArguments[nIndex++] = Any(mxParentWindow);
1308 for (sal_uInt32 nPaneIndex=0; nPaneIndex<mpPaneContainer->maPanes.size(); ++nPaneIndex)
1310 if ( ! mpPaneContainer->maPanes[nPaneIndex]->mbIsActive)
1311 continue;
1313 const Reference<awt::XWindow> xBorderWindow (
1314 mpPaneContainer->maPanes[nPaneIndex]->mxBorderWindow);
1315 const Reference<awt::XWindow> xContentWindow (
1316 mpPaneContainer->maPanes[nPaneIndex]->mxContentWindow);
1317 const Reference<awt::XWindow2> xBorderWindow2(xBorderWindow, UNO_QUERY);
1318 if (xBorderWindow.is()
1319 && xContentWindow.is()
1320 && ( ! xBorderWindow2.is() || xBorderWindow2->isVisible()))
1322 aArguments[nIndex++] = Any(xBorderWindow);
1323 aArguments[nIndex++] = Any(xContentWindow);
1327 aArguments.realloc(nIndex);
1328 rtl::Reference<PresenterPaneBorderManager> pManager (
1329 new PresenterPaneBorderManager (
1330 mxComponentContext,
1331 mpPresenterController));
1332 pManager->initialize(aArguments);
1333 mxPaneBorderManager = Reference<XInterface>(static_cast<XWeak*>(pManager.get()));
1336 catch (RuntimeException&)
1339 #endif
1345 void PresenterWindowManager::Invalidate (void)
1347 mpPresenterController->GetPaintManager()->Invalidate(mxParentWindow);
1353 Reference<awt::XWindow> PresenterWindowManager::GetParentWindow (void) const
1355 return mxParentWindow;
1361 Reference<rendering::XCanvas> PresenterWindowManager::GetParentCanvas (void) const
1363 return mxParentCanvas;
1369 void PresenterWindowManager::Update (void)
1371 mxClipPolygon = NULL;
1372 mbIsLayoutPending = true;
1374 UpdateWindowList();
1375 Invalidate();
1381 void PresenterWindowManager::ThrowIfDisposed (void) const
1382 throw (::com::sun::star::lang::DisposedException)
1384 if (rBHelper.bDisposed || rBHelper.bInDispose)
1386 throw lang::DisposedException (
1387 OUString(RTL_CONSTASCII_USTRINGPARAM(
1388 "PresenterWindowManager has already been disposed")),
1389 const_cast<uno::XWeak*>(static_cast<const uno::XWeak*>(this)));
1395 namespace {
1397 //===== ModeChangeAnimation ===================================================
1399 class ModeChangeAnimation : public PresenterAnimation
1401 public:
1402 ModeChangeAnimation (
1403 const ::boost::shared_ptr<PresenterSprite>& rpSprite,
1404 const Reference<rendering::XSpriteCanvas>& rxCanvas)
1405 : PresenterAnimation (0, 1000, 20),
1406 mpSprite(rpSprite),
1407 mxCanvas(rxCanvas)
1411 virtual void Run (const double nProgress, const sal_uInt64 nCurrentTime)
1413 (void)nCurrentTime;
1414 mpSprite->SetAlpha(1.0 - nProgress);
1415 mxCanvas->updateScreen(sal_False);
1418 private:
1419 ::boost::shared_ptr<PresenterSprite> mpSprite;
1420 Reference<rendering::XSpriteCanvas> mxCanvas;
1426 ModeChangeAnimationStarter::ModeChangeAnimationStarter (
1427 const Reference<drawing::framework::XConfigurationController>& rxConfigurationController,
1428 const Reference<awt::XWindow>& rxWindow,
1429 const Reference<rendering::XSpriteCanvas>& rxCanvas,
1430 const ::boost::shared_ptr<PresenterAnimator>& rpAnimator)
1431 : ModeChangeAnimationStarterInterfaceBase(m_aMutex),
1432 mxConfigurationController(rxConfigurationController),
1433 mpAnimator(rpAnimator),
1434 mpSprite(new PresenterSprite()),
1435 mxCanvas(rxCanvas)
1437 OSL_ASSERT(rxWindow.is());
1438 OSL_ASSERT(rxCanvas.is());
1440 // Get the bitmap of the background.
1441 Reference<rendering::XBitmap> xBackgroundBitmap (rxCanvas, UNO_QUERY);
1442 if ( ! xBackgroundBitmap.is())
1443 return;
1445 // Create the sprite.
1446 const awt::Rectangle aWindowSize (rxWindow->getPosSize());
1447 mpSprite->SetFactory(rxCanvas);
1448 mpSprite->Resize(geometry::RealSize2D(aWindowSize.Width, aWindowSize.Height));
1449 mpSprite->SetPriority(10);
1451 // Fill it with the background inside the bounding box.
1452 const rendering::ViewState aViewState (
1453 geometry::AffineMatrix2D(1,0,0, 0,1,0),
1454 NULL);
1455 const rendering::RenderState aRenderState (
1456 geometry::AffineMatrix2D(1,0,0, 0,1,0),
1457 NULL,
1458 Sequence<double>(4),
1459 rendering::CompositeOperation::SOURCE);
1460 Reference<rendering::XCanvas> xSpriteCanvas (mpSprite->GetCanvas());
1461 if (xSpriteCanvas.is())
1463 xSpriteCanvas->drawBitmap(xBackgroundBitmap, aViewState, aRenderState);
1464 mpSprite->Show();
1467 // Register as listener to be notified when the new panes are visible
1468 // and the sprite can be faded out.
1469 mxConfigurationController->addConfigurationChangeListener(
1470 this,
1471 A2S("ConfigurationUpdateEnd"),
1472 Any());
1478 ModeChangeAnimationStarter::~ModeChangeAnimationStarter (void)
1485 void SAL_CALL ModeChangeAnimationStarter::disposing (void)
1487 mxConfigurationController = NULL;
1488 mpAnimator.reset();
1489 mpSprite.reset();
1495 // XConfigurationChangeListener
1497 void SAL_CALL ModeChangeAnimationStarter::notifyConfigurationChange (
1498 const com::sun::star::drawing::framework::ConfigurationChangeEvent& rEvent)
1499 throw (com::sun::star::uno::RuntimeException)
1501 (void)rEvent;
1503 // Start the actual animation.
1504 mpAnimator->AddAnimation(SharedPresenterAnimation(new ModeChangeAnimation(
1505 mpSprite,
1506 mxCanvas)));
1508 mxConfigurationController->removeConfigurationChangeListener(this);
1514 // XEventListener
1516 void SAL_CALL ModeChangeAnimationStarter::disposing (
1517 const com::sun::star::lang::EventObject& rEvent)
1518 throw (com::sun::star::uno::RuntimeException)
1520 if (rEvent.Source == mxConfigurationController)
1521 mxConfigurationController = NULL;
1526 } // end of anonymous namespace
1529 } } // end of namespace ::sdext::presenter