1 /*************************************************************************
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
5 * Copyright 2008 by Sun Microsystems, Inc.
7 * OpenOffice.org - a multi-platform office productivity suite
9 * $RCSfile: PresenterWindowManager.cxx,v $
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>
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
{
84 typedef ::cppu::WeakComponentImplHelper1
<
85 css::drawing::framework::XConfigurationChangeListener
86 > ModeChangeAnimationStarterInterfaceBase
;
88 class ModeChangeAnimationStarter
89 : protected ::cppu::BaseMutex
,
90 public ModeChangeAnimationStarterInterfaceBase
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
);
110 virtual void SAL_CALL
disposing (
111 const com::sun::star::lang::EventObject
& rEvent
)
112 throw (com::sun::star::uno::RuntimeException
);
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
),
135 mxPaneBorderManager(),
136 mpPaneBorderPainter(),
137 mpPaneContainer(rpPaneContainer
),
138 mbIsLayoutPending(true),
139 mbIsLayouting(false),
141 mpBackgroundBitmap(),
142 mxScaledBackgroundBitmap(),
143 maPaneBackgroundColor(),
145 meLayoutMode(Generic
),
146 mbIsSlideSorterActive(false),
147 mbIsHelpViewActive(false),
149 mbIsMouseClickPending(false)
157 PresenterWindowManager::~PresenterWindowManager (void)
164 void SAL_CALL
PresenterWindowManager::disposing (void)
170 Reference
<lang::XComponent
> xComponent (mxPaneBorderManager
, UNO_QUERY
);
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);
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
;
208 mxParentWindow
= rxPane
->getWindow();
209 mxParentCanvas
= rxPane
->getCanvas();
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
);
226 xPeer
->setBackground(util::Color(0xff000000));
233 void PresenterWindowManager::SetTheme (const ::boost::shared_ptr
<PresenterTheme
>& 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
);
256 if ( ! rpDescriptor
->mxContentWindow
.is())
258 OSL_ASSERT(rpDescriptor
->mxContentWindow
.is());
262 mbIsLayoutPending
= true;
264 Reference
<awt::XWindow
> xBorderWindow (rpDescriptor
->mxBorderWindow
);
265 OSL_ASSERT(xBorderWindow
.is());
266 if (xBorderWindow
.is() && ! rpDescriptor
->mbIsSprite
)
270 xBorderWindow
->addWindowListener(this);
271 xBorderWindow
->addFocusListener(this);
272 #ifndef ENABLE_PANE_RESIZING
273 xBorderWindow
->addMouseListener(this);
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
)
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
,
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
)
373 if (rEvent
.Source
== mxParentWindow
)
379 Reference
<awt::XWindow
> xWindow (rEvent
.Source
,UNO_QUERY
);
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
)
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
)
419 void SAL_CALL
PresenterWindowManager::windowHidden (const lang::EventObject
& rEvent
)
420 throw (RuntimeException
)
428 //----- XPaintListener --------------------------------------------------------
430 void SAL_CALL
PresenterWindowManager::windowPaint (const awt::PaintEvent
& rEvent
)
431 throw (RuntimeException
)
435 if ( ! mxParentWindow
.is())
437 if ( ! mxParentCanvas
.is())
440 if (mpTheme
.get()!=NULL
)
444 if (mbIsLayoutPending
)
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
&)
464 //----- XMouseListener --------------------------------------------------------
466 void SAL_CALL
PresenterWindowManager::mousePressed (const css::awt::MouseEvent
& rEvent
)
467 throw(css::uno::RuntimeException
)
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
);
493 void SAL_CALL
PresenterWindowManager::mouseEntered (const css::awt::MouseEvent
& rEvent
)
494 throw(css::uno::RuntimeException
)
497 mbIsMouseClickPending
= false;
503 void SAL_CALL
PresenterWindowManager::mouseExited (const css::awt::MouseEvent
& rEvent
)
504 throw(css::uno::RuntimeException
)
507 mbIsMouseClickPending
= false;
513 //----- XFocusListener --------------------------------------------------------
515 void SAL_CALL
PresenterWindowManager::focusGained (const css::awt::FocusEvent
& rEvent
)
516 throw (css::uno::RuntimeException
)
525 void SAL_CALL
PresenterWindowManager::focusLost (const css::awt::FocusEvent
& rEvent
)
526 throw (css::uno::RuntimeException
)
535 //----- XEventListener --------------------------------------------------------
537 void SAL_CALL
PresenterWindowManager::disposing (const lang::EventObject
& rEvent
)
538 throw (RuntimeException
)
540 if (rEvent
.Source
== mxParentWindow
)
541 mxParentWindow
= NULL
;
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
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
)
568 if ((*iPane
)->mbIsSprite
)
570 if ( ! (*iPane
)->mxPane
.is())
572 if ( ! (*iPane
)->mxBorderWindow
.is())
574 Reference
<awt::XWindow
> xBorderWindow ((*iPane
)->mxBorderWindow
);
575 if ( ! xBorderWindow
.is())
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(
584 if (aBorderUpdateBox
.Width
<=0 || aBorderUpdateBox
.Height
<=0)
587 const awt::Rectangle
aLocalBorderUpdateBox(
588 PresenterGeometryHelper::TranslateRectangle(
593 // Invalidate the area of the content window.
594 mpPresenterController
->GetPaintManager()->Invalidate(
596 aLocalBorderUpdateBox
,
597 sal_Int16(awt::InvalidateStyle::CHILDREN
598 | awt::InvalidateStyle::NOTRANSPARENT
));
600 catch (RuntimeException
&)
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
,
629 NotifyLayoutModeChange();
636 PresenterWindowManager::LayoutMode
PresenterWindowManager::GetLayoutMode (void) const
644 void PresenterWindowManager::SetSlideSorterState (bool bIsActive
)
646 if (mbIsSlideSorterActive
!= bIsActive
)
648 mbIsSlideSorterActive
= bIsActive
;
649 if (mbIsSlideSorterActive
)
650 mbIsHelpViewActive
= false;
652 mpPresenterController
->RequestViews(
653 mbIsSlideSorterActive
,
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
,
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.
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
)
744 switch (meLayoutMode
)
748 LayoutStandardMode();
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
,
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
,
815 aNextSlideOuterBox
.Width
,
816 aNextSlideOuterBox
.Height
);
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,
847 nSlidePreviewTop
= (aBox
.Height
848 - aToolBarBox
.Y2
+ aToolBarBox
.Y1
- aNotesViewOuterSize
.Height
) / 2;
849 SetPanePosSizeAbsolute (
850 PresenterPaneFactory::msNotesPaneURL
,
851 aBox
.Width
- aNotesViewOuterSize
.Width
- nGap
,
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
,
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(
884 PresenterPaneFactory::msNextSlidePreviewPaneURL
));
885 SetPanePosSizeAbsolute (
886 PresenterPaneFactory::msNextSlidePreviewPaneURL
,
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
),
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,
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
,
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
;
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
,
981 return geometry::RealRectangle2D(
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 (
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 (
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())
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
;
1128 // This update of the window size was initiated by
1129 // Layout(). Therefore the window size does not have to be
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
)
1145 if ( ! mxParentWindow
.is())
1148 Reference
<rendering::XGraphicDevice
> xDevice (mxParentCanvas
->getDevice());
1149 if ( ! xDevice
.is())
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),
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
,
1186 rendering::StrokeAttributes(),
1187 rendering::TexturingMode::REPEAT
,
1188 rendering::TexturingMode::REPEAT
);
1190 mxParentCanvas
->fillTexturedPolyPolygon(
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(
1214 void PresenterWindowManager::ProvideBackgroundBitmap (void)
1216 if ( ! mxScaledBackgroundBitmap
.is())
1218 Reference
<rendering::XBitmap
> xBitmap (mpBackgroundBitmap
->GetNormalBitmap());
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
;
1231 aSize
.Height
= xBitmap
->getSize().Height
;
1232 if (bStretchHorizontal
)
1233 aSize
.Width
= mxParentWindow
->getPosSize().Width
;
1235 aSize
.Width
= xBitmap
->getSize().Width
;
1236 mxScaledBackgroundBitmap
= xBitmap
->getScaledBitmap(aSize
, sal_False
);
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
)
1265 if ( ! pDescriptor
->mbIsOpaque
)
1267 if ( ! pDescriptor
->mxBorderWindow
.is() || ! pDescriptor
->mxContentWindow
.is())
1269 Reference
<awt::XWindow2
> xWindow (pDescriptor
->mxBorderWindow
, UNO_QUERY
);
1270 if (xWindow
.is() && ! xWindow
->isVisible())
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(
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());
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
)
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 (
1331 mpPresenterController
));
1332 pManager
->initialize(aArguments
);
1333 mxPaneBorderManager
= Reference
<XInterface
>(static_cast<XWeak
*>(pManager
.get()));
1336 catch (RuntimeException
&)
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;
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)));
1397 //===== ModeChangeAnimation ===================================================
1399 class ModeChangeAnimation
: public PresenterAnimation
1402 ModeChangeAnimation (
1403 const ::boost::shared_ptr
<PresenterSprite
>& rpSprite
,
1404 const Reference
<rendering::XSpriteCanvas
>& rxCanvas
)
1405 : PresenterAnimation (0, 1000, 20),
1411 virtual void Run (const double nProgress
, const sal_uInt64 nCurrentTime
)
1414 mpSprite
->SetAlpha(1.0 - nProgress
);
1415 mxCanvas
->updateScreen(sal_False
);
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()),
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())
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),
1455 const rendering::RenderState
aRenderState (
1456 geometry::AffineMatrix2D(1,0,0, 0,1,0),
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
);
1467 // Register as listener to be notified when the new panes are visible
1468 // and the sprite can be faded out.
1469 mxConfigurationController
->addConfigurationChangeListener(
1471 A2S("ConfigurationUpdateEnd"),
1478 ModeChangeAnimationStarter::~ModeChangeAnimationStarter (void)
1485 void SAL_CALL
ModeChangeAnimationStarter::disposing (void)
1487 mxConfigurationController
= NULL
;
1495 // XConfigurationChangeListener
1497 void SAL_CALL
ModeChangeAnimationStarter::notifyConfigurationChange (
1498 const com::sun::star::drawing::framework::ConfigurationChangeEvent
& rEvent
)
1499 throw (com::sun::star::uno::RuntimeException
)
1503 // Start the actual animation.
1504 mpAnimator
->AddAnimation(SharedPresenterAnimation(new ModeChangeAnimation(
1508 mxConfigurationController
->removeConfigurationChangeListener(this);
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