Updated core
[LibreOffice.git] / sdext / source / presenter / PresenterWindowManager.cxx
blobfddf3e53554e194ed7dc1662fcfd2a5db6678166
1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 /*
3 * This file is part of the LibreOffice project.
5 * This Source Code Form is subject to the terms of the Mozilla Public
6 * License, v. 2.0. If a copy of the MPL was not distributed with this
7 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
9 * This file incorporates work covered by the following license notice:
11 * Licensed to the Apache Software Foundation (ASF) under one or more
12 * contributor license agreements. See the NOTICE file distributed
13 * with this work for additional information regarding copyright
14 * ownership. The ASF licenses this file to you under the Apache
15 * License, Version 2.0 (the "License"); you may not use this file
16 * except in compliance with the License. You may obtain a copy of
17 * the License at http://www.apache.org/licenses/LICENSE-2.0 .
20 #undef ENABLE_PANE_RESIZING
21 //#define ENABLE_PANE_RESIZING
23 #include "vcl/svapp.hxx"
24 #include "PresenterWindowManager.hxx"
25 #include "PresenterController.hxx"
26 #include "PresenterGeometryHelper.hxx"
27 #include "PresenterHelper.hxx"
28 #include "PresenterPaintManager.hxx"
29 #include "PresenterPaneBase.hxx"
30 #include "PresenterPaneBorderManager.hxx"
31 #include "PresenterPaneBorderPainter.hxx"
32 #include "PresenterPaneContainer.hxx"
33 #include "PresenterPaneFactory.hxx"
34 #include "PresenterSprite.hxx"
35 #include "PresenterToolBar.hxx"
36 #include "PresenterViewFactory.hxx"
37 #include "PresenterTheme.hxx"
38 #include <com/sun/star/awt/InvalidateStyle.hpp>
39 #include <com/sun/star/awt/PosSize.hpp>
40 #include <com/sun/star/awt/SystemPointer.hpp>
41 #include <com/sun/star/awt/XDevice.hpp>
42 #include <com/sun/star/awt/XWindow2.hpp>
43 #include <com/sun/star/awt/XWindowPeer.hpp>
44 #include <com/sun/star/awt/WindowAttribute.hpp>
45 #include <com/sun/star/container/XChild.hpp>
46 #include <com/sun/star/drawing/framework/ResourceId.hpp>
47 #include <com/sun/star/rendering/CompositeOperation.hpp>
48 #include <com/sun/star/rendering/FillRule.hpp>
49 #include <com/sun/star/rendering/PathCapType.hpp>
50 #include <com/sun/star/rendering/PathJoinType.hpp>
51 #include <com/sun/star/rendering/Texture.hpp>
52 #include <com/sun/star/rendering/TexturingMode.hpp>
53 #include <com/sun/star/rendering/XSpriteCanvas.hpp>
54 #include <math.h>
56 using namespace ::com::sun::star;
57 using namespace ::com::sun::star::uno;
58 using namespace ::com::sun::star::drawing::framework;
60 namespace sdext { namespace presenter {
62 //===== PresenterWindowManager ================================================
64 PresenterWindowManager::PresenterWindowManager (
65 const Reference<XComponentContext>& rxContext,
66 const ::rtl::Reference<PresenterPaneContainer>& rpPaneContainer,
67 const ::rtl::Reference<PresenterController>& rpPresenterController)
68 : PresenterWindowManagerInterfaceBase(m_aMutex),
69 mxComponentContext(rxContext),
70 mpPresenterController(rpPresenterController),
71 mxParentWindow(),
72 mxParentCanvas(),
73 mxPaneBorderManager(),
74 mpPaneBorderPainter(),
75 mpPaneContainer(rpPaneContainer),
76 mbIsLayoutPending(true),
77 mbIsLayouting(false),
78 mpTheme(),
79 mpBackgroundBitmap(),
80 mxScaledBackgroundBitmap(),
81 maPaneBackgroundColor(),
82 mxClipPolygon(),
83 meLayoutMode(LM_Generic),
84 mbIsSlideSorterActive(false),
85 mbIsHelpViewActive(false),
86 maLayoutListeners(),
87 mbIsMouseClickPending(false)
89 UpdateWindowList();
92 PresenterWindowManager::~PresenterWindowManager (void)
96 void SAL_CALL PresenterWindowManager::disposing (void)
98 NotifyDisposing();
100 SetParentPane(NULL);
102 Reference<lang::XComponent> xComponent (mxPaneBorderManager, UNO_QUERY);
103 if (xComponent.is())
104 xComponent->dispose();
105 mxPaneBorderManager = NULL;
107 PresenterPaneContainer::PaneList::const_iterator iPane;
108 PresenterPaneContainer::PaneList::const_iterator iEnd (mpPaneContainer->maPanes.end());
109 for (iPane=mpPaneContainer->maPanes.begin(); iPane!=iEnd; ++iPane)
111 if ((*iPane)->mxBorderWindow.is())
113 (*iPane)->mxBorderWindow->removeWindowListener(this);
114 (*iPane)->mxBorderWindow->removeFocusListener(this);
115 #ifndef ENABLE_PANE_RESIZING
116 (*iPane)->mxBorderWindow->removeMouseListener(this);
117 #endif
122 void PresenterWindowManager::SetParentPane (
123 const Reference<drawing::framework::XPane>& rxPane)
125 if (mxParentWindow.is())
127 mxParentWindow->removeWindowListener(this);
128 mxParentWindow->removePaintListener(this);
129 mxParentWindow->removeMouseListener(this);
130 mxParentWindow->removeFocusListener(this);
132 mxParentWindow = NULL;
133 mxParentCanvas = NULL;
135 if (rxPane.is())
137 mxParentWindow = rxPane->getWindow();
138 mxParentCanvas = rxPane->getCanvas();
140 else
142 mxParentWindow = NULL;
145 if (mxParentWindow.is())
147 mxParentWindow->addWindowListener(this);
148 mxParentWindow->addPaintListener(this);
149 mxParentWindow->addMouseListener(this);
150 mxParentWindow->addFocusListener(this);
152 // We paint our own background, make that of the parent window transparent.
153 Reference<awt::XWindowPeer> xPeer (mxParentWindow, UNO_QUERY);
154 if (xPeer.is())
155 xPeer->setBackground(util::Color(0xff000000));
159 void PresenterWindowManager::SetTheme (const ::boost::shared_ptr<PresenterTheme>& rpTheme)
161 mpTheme = rpTheme;
163 // Get background bitmap or background color from the theme.
165 if (mpTheme.get() != NULL)
167 mpBackgroundBitmap = mpTheme->GetBitmap(OUString(), "Background");
171 void PresenterWindowManager::NotifyViewCreation (const Reference<XView>& rxView)
173 PresenterPaneContainer::SharedPaneDescriptor pDescriptor (
174 mpPaneContainer->FindPaneId(rxView->getResourceId()->getAnchor()));
175 OSL_ASSERT(pDescriptor.get() != NULL);
176 if (pDescriptor.get() != NULL)
178 Layout();
180 mpPresenterController->GetPaintManager()->Invalidate(
181 pDescriptor->mxContentWindow,
182 (sal_Int16)(awt::InvalidateStyle::TRANSPARENT
183 | awt::InvalidateStyle::CHILDREN));
187 void PresenterWindowManager::SetPanePosSizeAbsolute (
188 const OUString& rsPaneURL,
189 const double nX,
190 const double nY,
191 const double nWidth,
192 const double nHeight)
194 PresenterPaneContainer::SharedPaneDescriptor pDescriptor (
195 mpPaneContainer->FindPaneURL(rsPaneURL));
196 if (pDescriptor.get() != NULL)
198 awt::Rectangle aParentBox = mxParentWindow->getPosSize();
199 if (aParentBox.Width > 0 && aParentBox.Height > 0)
201 pDescriptor->mnLeft = nX / aParentBox.Width;
202 pDescriptor->mnTop = nY / aParentBox.Height;
203 pDescriptor->mnRight = (nX + nWidth) / aParentBox.Width;
204 pDescriptor->mnBottom = (nY + nHeight) / aParentBox.Height;
206 if (pDescriptor->mxBorderWindow.is())
207 pDescriptor->mxBorderWindow->setPosSize(
208 ::sal::static_int_cast<sal_Int32>(nX),
209 ::sal::static_int_cast<sal_Int32>(nY),
210 ::sal::static_int_cast<sal_Int32>(nWidth),
211 ::sal::static_int_cast<sal_Int32>(nHeight),
212 awt::PosSize::POSSIZE);
216 void PresenterWindowManager::SetPaneBorderPainter (
217 const ::rtl::Reference<PresenterPaneBorderPainter>& rPainter)
219 mpPaneBorderPainter = rPainter;
222 //----- XWindowListener -------------------------------------------------------
224 void SAL_CALL PresenterWindowManager::windowResized (const awt::WindowEvent& rEvent)
225 throw (RuntimeException)
227 ThrowIfDisposed();
228 if (rEvent.Source == mxParentWindow)
230 Layout();
232 else
234 Reference<awt::XWindow> xWindow (rEvent.Source,UNO_QUERY);
235 if (xWindow.is())
237 UpdateWindowSize(xWindow);
239 // Make sure the background of a transparent window is painted.
240 mpPresenterController->GetPaintManager()->Invalidate(mxParentWindow);
245 void SAL_CALL PresenterWindowManager::windowMoved (const awt::WindowEvent& rEvent)
246 throw (RuntimeException)
248 ThrowIfDisposed();
249 if (rEvent.Source != mxParentWindow)
251 Reference<awt::XWindow> xWindow (rEvent.Source,UNO_QUERY);
252 UpdateWindowSize(xWindow);
254 // Make sure the background of a transparent window is painted.
255 mpPresenterController->GetPaintManager()->Invalidate(xWindow);
259 void SAL_CALL PresenterWindowManager::windowShown (const lang::EventObject& rEvent)
260 throw (RuntimeException)
262 (void)rEvent;
265 void SAL_CALL PresenterWindowManager::windowHidden (const lang::EventObject& rEvent)
266 throw (RuntimeException)
268 (void)rEvent;
271 //----- XPaintListener --------------------------------------------------------
273 void SAL_CALL PresenterWindowManager::windowPaint (const awt::PaintEvent& rEvent)
274 throw (RuntimeException)
276 ThrowIfDisposed();
278 if ( ! mxParentWindow.is())
279 return;
280 if ( ! mxParentCanvas.is())
281 return;
283 if (mpTheme.get()!=NULL)
287 if (mbIsLayoutPending)
288 Layout();
289 PaintBackground(rEvent.UpdateRect);
290 if ( ! PaintChildren(rEvent))
292 Reference<rendering::XSpriteCanvas> xSpriteCanvas (mxParentCanvas, UNO_QUERY);
293 // if (xSpriteCanvas.is())
294 // xSpriteCanvas->updateScreen(sal_False);
297 catch (RuntimeException&)
299 OSL_FAIL("paint failed!");
304 //----- XMouseListener --------------------------------------------------------
306 void SAL_CALL PresenterWindowManager::mousePressed (const css::awt::MouseEvent& rEvent)
307 throw(css::uno::RuntimeException)
309 (void)rEvent;
310 mbIsMouseClickPending = true;
313 void SAL_CALL PresenterWindowManager::mouseReleased (const css::awt::MouseEvent& rEvent)
314 throw(css::uno::RuntimeException)
316 #ifndef ENABLE_PANE_RESIZING
317 if (mbIsMouseClickPending)
319 mbIsMouseClickPending = false;
320 mpPresenterController->HandleMouseClick(rEvent);
322 #else
323 (void)rEvent;
324 #endif
327 void SAL_CALL PresenterWindowManager::mouseEntered (const css::awt::MouseEvent& rEvent)
328 throw(css::uno::RuntimeException)
330 (void)rEvent;
331 mbIsMouseClickPending = false;
334 void SAL_CALL PresenterWindowManager::mouseExited (const css::awt::MouseEvent& rEvent)
335 throw(css::uno::RuntimeException)
337 (void)rEvent;
338 mbIsMouseClickPending = false;
341 //----- XFocusListener --------------------------------------------------------
343 void SAL_CALL PresenterWindowManager::focusGained (const css::awt::FocusEvent& rEvent)
344 throw (css::uno::RuntimeException)
346 ThrowIfDisposed();
347 (void)rEvent;
348 OSL_TRACE("PresenterWindowManager::focusGained window %x\n",
349 rEvent.Source.get());
352 void SAL_CALL PresenterWindowManager::focusLost (const css::awt::FocusEvent& rEvent)
353 throw (css::uno::RuntimeException)
355 ThrowIfDisposed();
356 (void)rEvent;
359 //----- XEventListener --------------------------------------------------------
361 void SAL_CALL PresenterWindowManager::disposing (const lang::EventObject& rEvent)
362 throw (RuntimeException)
364 if (rEvent.Source == mxParentWindow)
365 mxParentWindow = NULL;
366 else
368 Reference<awt::XWindow> xWindow (rEvent.Source, UNO_QUERY);
372 //-----------------------------------------------------------------------------
374 bool PresenterWindowManager::PaintChildren (const awt::PaintEvent& rEvent) const
376 bool bChildInvalidated (false);
378 // Call windowPaint on all children that lie in or touch the
379 // update rectangle.
380 PresenterPaneContainer::PaneList::const_iterator iPane;
381 PresenterPaneContainer::PaneList::const_iterator iEnd (mpPaneContainer->maPanes.end());
382 for (iPane=mpPaneContainer->maPanes.begin(); iPane!=iEnd; ++iPane)
386 // Make sure that the pane shall and can be painted.
387 if ( ! (*iPane)->mbIsActive)
388 continue;
389 if ((*iPane)->mbIsSprite)
390 continue;
391 if ( ! (*iPane)->mxPane.is())
392 continue;
393 if ( ! (*iPane)->mxBorderWindow.is())
394 continue;
395 Reference<awt::XWindow> xBorderWindow ((*iPane)->mxBorderWindow);
396 if ( ! xBorderWindow.is())
397 continue;
399 // Get the area in which the border of the pane has to be painted.
400 const awt::Rectangle aBorderBox (xBorderWindow->getPosSize());
401 const awt::Rectangle aBorderUpdateBox(
402 PresenterGeometryHelper::Intersection(
403 rEvent.UpdateRect,
404 aBorderBox));
405 if (aBorderUpdateBox.Width<=0 || aBorderUpdateBox.Height<=0)
406 continue;
408 const awt::Rectangle aLocalBorderUpdateBox(
409 PresenterGeometryHelper::TranslateRectangle(
410 aBorderUpdateBox,
411 -aBorderBox.X,
412 -aBorderBox.Y));
414 // Invalidate the area of the content window.
415 mpPresenterController->GetPaintManager()->Invalidate(
416 xBorderWindow,
417 aLocalBorderUpdateBox,
418 sal_Int16(awt::InvalidateStyle::CHILDREN
419 | awt::InvalidateStyle::NOTRANSPARENT));
421 catch (RuntimeException&)
423 OSL_FAIL("paint children failed!");
427 return bChildInvalidated;
430 void PresenterWindowManager::SetLayoutMode (const LayoutMode eMode)
432 OSL_ASSERT(mpPresenterController.get() != NULL);
434 if (meLayoutMode != eMode
435 || mbIsSlideSorterActive
436 || mbIsHelpViewActive)
438 meLayoutMode = eMode;
439 mbIsSlideSorterActive = false;
440 mbIsHelpViewActive = false;
442 mpPresenterController->RequestViews(
443 mbIsSlideSorterActive,
444 meLayoutMode==LM_Notes,
445 mbIsHelpViewActive);
446 Layout();
447 NotifyLayoutModeChange();
451 void PresenterWindowManager::SetSlideSorterState (bool bIsActive)
453 if (mbIsSlideSorterActive != bIsActive)
455 mbIsSlideSorterActive = bIsActive;
456 if (mbIsSlideSorterActive)
457 mbIsHelpViewActive = false;
458 StoreViewMode(GetViewMode());
460 mpPresenterController->RequestViews(
461 mbIsSlideSorterActive,
462 meLayoutMode==LM_Notes,
463 mbIsHelpViewActive);
464 Layout();
465 NotifyLayoutModeChange();
469 void PresenterWindowManager::SetHelpViewState (bool bIsActive)
471 if (mbIsHelpViewActive != bIsActive)
473 mbIsHelpViewActive = bIsActive;
474 if (mbIsHelpViewActive)
475 mbIsSlideSorterActive = false;
476 StoreViewMode(GetViewMode());
478 mpPresenterController->RequestViews(
479 mbIsSlideSorterActive,
480 meLayoutMode==LM_Notes,
481 mbIsHelpViewActive);
482 Layout();
483 NotifyLayoutModeChange();
487 void PresenterWindowManager::SetViewMode (const ViewMode eMode)
489 switch (eMode)
491 case VM_Standard:
492 SetSlideSorterState(false);
493 SetHelpViewState(false);
494 SetLayoutMode(LM_Standard);
495 break;
497 case VM_Notes:
498 SetSlideSorterState(false);
499 SetHelpViewState(false);
500 SetLayoutMode(LM_Notes);
501 break;
503 case VM_SlideOverview:
504 SetHelpViewState(false);
505 SetSlideSorterState(true);
506 break;
508 case VM_Help:
509 SetHelpViewState(true);
510 SetSlideSorterState(false);
511 break;
514 StoreViewMode(eMode);
517 PresenterWindowManager::ViewMode PresenterWindowManager::GetViewMode (void) const
519 if (mbIsHelpViewActive)
520 return VM_Help;
521 else if (mbIsSlideSorterActive)
522 return VM_SlideOverview;
523 else if (meLayoutMode == LM_Notes)
524 return VM_Notes;
525 else
526 return VM_Standard;
529 void PresenterWindowManager::RestoreViewMode (void)
531 sal_Int32 nMode (0);
532 PresenterConfigurationAccess aConfiguration (
533 mxComponentContext,
534 OUString("/org.openoffice.Office.PresenterScreen/"),
535 PresenterConfigurationAccess::READ_ONLY);
536 aConfiguration.GetConfigurationNode("Presenter/InitialViewMode") >>= nMode;
537 switch (nMode)
539 default:
540 case 0:
541 SetViewMode(VM_Standard);
542 break;
544 case 1:
545 SetViewMode(VM_Notes);
546 break;
548 case 2:
549 SetViewMode(VM_SlideOverview);
550 break;
554 void PresenterWindowManager::StoreViewMode (const ViewMode eViewMode)
558 PresenterConfigurationAccess aConfiguration (
559 mxComponentContext,
560 OUString("/org.openoffice.Office.PresenterScreen/"),
561 PresenterConfigurationAccess::READ_WRITE);
562 aConfiguration.GoToChild(OUString("Presenter"));
563 Any aValue;
564 switch (eViewMode)
566 default:
567 case VM_Standard:
568 aValue = Any(sal_Int32(0));
569 break;
571 case VM_Notes:
572 aValue = Any(sal_Int32(1));
573 break;
575 case VM_SlideOverview:
576 aValue = Any(sal_Int32(2));
577 break;
580 aConfiguration.SetProperty ("InitialViewMode", aValue);
581 aConfiguration.CommitChanges();
583 catch (Exception&)
588 void PresenterWindowManager::AddLayoutListener (
589 const Reference<document::XEventListener>& rxListener)
591 maLayoutListeners.push_back(rxListener);
594 void PresenterWindowManager::RemoveLayoutListener (
595 const Reference<document::XEventListener>& rxListener)
597 LayoutListenerContainer::iterator iListener (maLayoutListeners.begin());
598 LayoutListenerContainer::iterator iEnd (maLayoutListeners.end());
599 for ( ; iListener!=iEnd; ++iListener)
601 if (*iListener == rxListener)
603 maLayoutListeners.erase(iListener);
604 // Assume that there are no multiple entries.
605 break;
610 void PresenterWindowManager::Layout (void)
612 if (mxParentWindow.is() && ! mbIsLayouting)
614 mbIsLayoutPending = false;
615 mbIsLayouting = true;
616 mxScaledBackgroundBitmap = NULL;
617 mxClipPolygon = NULL;
621 if (mbIsSlideSorterActive)
622 LayoutSlideSorterMode();
623 else if (mbIsHelpViewActive)
624 LayoutHelpMode();
625 else
626 switch (meLayoutMode)
628 case LM_Standard:
629 default:
630 LayoutStandardMode();
631 break;
633 case LM_Notes:
634 LayoutNotesMode();
635 break;
638 catch (Exception&)
640 OSL_ASSERT(false);
641 throw;
644 mbIsLayouting = false;
648 void PresenterWindowManager::LayoutStandardMode (void)
650 awt::Rectangle aBox = mxParentWindow->getPosSize();
652 const double nGoldenRatio ((1 + sqrt(5.0)) / 2);
653 const double nGap (20);
654 const double nHorizontalSlideDivide (aBox.Width / nGoldenRatio);
655 double nSlidePreviewTop (0);
658 // For the current slide view calculate the outer height from the outer
659 // width. This takes into acount the slide aspect ratio and thus has to
660 // go over the inner pane size.
661 PresenterPaneContainer::SharedPaneDescriptor pPane (
662 mpPaneContainer->FindPaneURL(PresenterPaneFactory::msCurrentSlidePreviewPaneURL));
663 if (pPane.get() != NULL)
665 const awt::Size aCurrentSlideOuterBox(CalculatePaneSize(
666 nHorizontalSlideDivide - 1.5*nGap,
667 PresenterPaneFactory::msCurrentSlidePreviewPaneURL));
668 nSlidePreviewTop = (aBox.Height - aCurrentSlideOuterBox.Height) / 2;
669 double Temp=nGap;
670 /// check whether RTL interface or not
671 if(Application::GetSettings().GetLayoutRTL())
672 Temp=aBox.Width - aCurrentSlideOuterBox.Width - nGap;
673 SetPanePosSizeAbsolute (
674 PresenterPaneFactory::msCurrentSlidePreviewPaneURL,
675 Temp,
676 nSlidePreviewTop,
677 aCurrentSlideOuterBox.Width,
678 aCurrentSlideOuterBox.Height);
681 // For the next slide view calculate the outer height from the outer
682 // width. This takes into acount the slide aspect ratio and thus has to
683 // go over the inner pane size.
684 pPane = mpPaneContainer->FindPaneURL(PresenterPaneFactory::msNextSlidePreviewPaneURL);
685 if (pPane.get() != NULL)
687 const awt::Size aNextSlideOuterBox (CalculatePaneSize(
688 aBox.Width - nHorizontalSlideDivide - 1.5*nGap,
689 PresenterPaneFactory::msNextSlidePreviewPaneURL));
690 double Temp=aBox.Width - aNextSlideOuterBox.Width - nGap;
691 /// check whether RTL interface or not
692 if(Application::GetSettings().GetLayoutRTL())
693 Temp=nGap;
694 SetPanePosSizeAbsolute (
695 PresenterPaneFactory::msNextSlidePreviewPaneURL,
696 Temp,
697 nSlidePreviewTop,
698 aNextSlideOuterBox.Width,
699 aNextSlideOuterBox.Height);
702 LayoutToolBar();
705 void PresenterWindowManager::LayoutNotesMode (void)
707 awt::Rectangle aBox = mxParentWindow->getPosSize();
709 const geometry::RealRectangle2D aToolBarBox (LayoutToolBar());
711 const double nGoldenRatio ((1 + sqrt(5.0)) / 2);
712 const double nGap (20);
713 const double nPrimaryWidth (aBox.Width / nGoldenRatio);
714 const double nSecondaryWidth (aBox.Width - nPrimaryWidth);
715 const double nTertiaryWidth (nSecondaryWidth / nGoldenRatio);
716 double nSlidePreviewTop (0);
717 double nNotesViewBottom (aToolBarBox.Y1 - nGap);
718 /// check whether RTL interface or not
721 // The notes view has no fixed aspect ratio.
722 PresenterPaneContainer::SharedPaneDescriptor pPane (
723 mpPaneContainer->FindPaneURL(PresenterPaneFactory::msNotesPaneURL));
724 if (pPane.get() != NULL)
726 const geometry::RealSize2D aNotesViewOuterSize(
727 nPrimaryWidth - 1.5*nGap + 0.5,
728 nNotesViewBottom);
729 nSlidePreviewTop = (aBox.Height
730 - aToolBarBox.Y2 + aToolBarBox.Y1 - aNotesViewOuterSize.Height) / 2;
731 /// check whether RTL interface or not
732 double Temp=aBox.Width - aNotesViewOuterSize.Width - nGap;
733 if(Application::GetSettings().GetLayoutRTL())
734 Temp=nGap;
735 SetPanePosSizeAbsolute (
736 PresenterPaneFactory::msNotesPaneURL,
737 Temp,
738 nSlidePreviewTop,
739 aNotesViewOuterSize.Width,
740 aNotesViewOuterSize.Height);
741 nNotesViewBottom = nSlidePreviewTop + aNotesViewOuterSize.Height;
744 // For the current slide view calculate the outer height from the outer
745 // width. This takes into acount the slide aspect ratio and thus has to
746 // go over the inner pane size.
747 pPane = mpPaneContainer->FindPaneURL(PresenterPaneFactory::msCurrentSlidePreviewPaneURL);
748 if (pPane.get() != NULL)
750 const awt::Size aCurrentSlideOuterBox(CalculatePaneSize(
751 nSecondaryWidth - 1.5*nGap,
752 PresenterPaneFactory::msCurrentSlidePreviewPaneURL));
753 /// check whether RTL interface or not
754 double Temp=nGap;
755 if(Application::GetSettings().GetLayoutRTL())
756 Temp=aBox.Width - aCurrentSlideOuterBox.Width - nGap;
757 SetPanePosSizeAbsolute (
758 PresenterPaneFactory::msCurrentSlidePreviewPaneURL,
759 Temp,
760 nSlidePreviewTop,
761 aCurrentSlideOuterBox.Width,
762 aCurrentSlideOuterBox.Height);
765 // For the next slide view calculate the outer height from the outer
766 // width. This takes into acount the slide aspect ratio and thus has to
767 // go over the inner pane size.
768 pPane = mpPaneContainer->FindPaneURL(PresenterPaneFactory::msNextSlidePreviewPaneURL);
769 if (pPane.get() != NULL)
771 const awt::Size aNextSlideOuterBox (CalculatePaneSize(
772 nTertiaryWidth,
773 PresenterPaneFactory::msNextSlidePreviewPaneURL));
774 /// check whether RTL interface or not
775 double Temp=nGap;
776 if(Application::GetSettings().GetLayoutRTL())
777 Temp=aBox.Width - aNextSlideOuterBox.Width - nGap;
778 SetPanePosSizeAbsolute (
779 PresenterPaneFactory::msNextSlidePreviewPaneURL,
780 Temp,
781 nNotesViewBottom - aNextSlideOuterBox.Height,
782 aNextSlideOuterBox.Width,
783 aNextSlideOuterBox.Height);
790 void PresenterWindowManager::LayoutSlideSorterMode (void)
792 const geometry::RealRectangle2D aToolBarBox (LayoutToolBar());
794 awt::Rectangle aWindowBox = mxParentWindow->getPosSize();
795 const double nGap (20);
796 SetPanePosSizeAbsolute(
797 mpPaneContainer->GetPaneURLForViewURL(PresenterViewFactory::msSlideSorterURL),
798 nGap,
799 nGap,
800 aWindowBox.Width - 2*nGap,
801 aToolBarBox.Y1 - 2*nGap);
804 void PresenterWindowManager::LayoutHelpMode (void)
806 const geometry::RealRectangle2D aToolBarBox (LayoutToolBar());
808 awt::Rectangle aWindowBox = mxParentWindow->getPosSize();
809 const double nGap (20);
810 const double nGoldenRatio ((1 + sqrt(5.0)) / 2);
811 const double nWidth = ::std::min(aWindowBox.Width - 2*nGap, aWindowBox.Width/nGoldenRatio);
812 SetPanePosSizeAbsolute(
813 mpPaneContainer->GetPaneURLForViewURL(PresenterViewFactory::msHelpViewURL),
814 (aWindowBox.Width - nWidth)/2,
815 nGap,
816 nWidth,
817 aToolBarBox.Y1 - 2*nGap);
820 geometry::RealRectangle2D PresenterWindowManager::LayoutToolBar (void)
822 double nToolBarWidth (400);
823 double nToolBarHeight (80);
825 // Get access to the tool bar.
826 PresenterPaneContainer::SharedPaneDescriptor pDescriptor(
827 mpPaneContainer->FindPaneURL(PresenterPaneFactory::msToolBarPaneURL));
828 if (pDescriptor.get() != NULL)
830 PresenterToolBarView* pToolBarView
831 = dynamic_cast<PresenterToolBarView*>(pDescriptor->mxView.get());
832 if (pToolBarView != NULL && pToolBarView->GetPresenterToolBar().is())
834 geometry::RealSize2D aSize (pToolBarView->GetPresenterToolBar()->GetMinimalSize());
836 if (mpPaneBorderPainter.is())
838 const awt::Rectangle aBox (mpPaneBorderPainter->addBorder (
839 PresenterPaneFactory::msToolBarPaneURL,
840 awt::Rectangle(
843 PresenterGeometryHelper::Round(aSize.Width),
844 PresenterGeometryHelper::Round(aSize.Height)),
845 css::drawing::framework::BorderType_TOTAL_BORDER));
847 nToolBarWidth = aBox.Width;
848 nToolBarHeight = aBox.Height;
850 else
852 nToolBarWidth = aSize.Width + 20;
853 nToolBarHeight = aSize.Height + 10;
858 const awt::Rectangle aBox = mxParentWindow->getPosSize();
859 const double nToolBarX ((aBox.Width - nToolBarWidth) / 2);
860 const double nToolBarY (aBox.Height - nToolBarHeight);
861 SetPanePosSizeAbsolute(
862 PresenterPaneFactory::msToolBarPaneURL,
863 nToolBarX,
864 nToolBarY,
865 nToolBarWidth,
866 nToolBarHeight);
868 return geometry::RealRectangle2D(
869 nToolBarX,
870 nToolBarY,
871 nToolBarX + nToolBarWidth - 1,
872 nToolBarY + nToolBarHeight - 1);
875 awt::Size PresenterWindowManager::CalculatePaneSize (
876 const double nOuterWidth,
877 const OUString& rsPaneURL)
879 // Calculate the inner width by removing the pane border.
880 awt::Rectangle aInnerBox (mpPaneBorderPainter->RemoveBorder (
881 rsPaneURL,
882 awt::Rectangle(0,0,
883 sal_Int32(nOuterWidth+0.5),sal_Int32(nOuterWidth)),
884 drawing::framework::BorderType_TOTAL_BORDER));
886 // Calculate the inner height with the help of the slide aspect ratio.
887 const double nCurrentSlideInnerHeight (
888 aInnerBox.Width / mpPresenterController->GetSlideAspectRatio());
890 // Add the pane border to get the outer box.
891 awt::Rectangle aOuterBox (mpPaneBorderPainter->AddBorder (
892 rsPaneURL,
893 awt::Rectangle(0,0,
894 aInnerBox.Width,sal_Int32(nCurrentSlideInnerHeight+0.5)),
895 drawing::framework::BorderType_TOTAL_BORDER));
897 return awt::Size(aOuterBox.Width, aOuterBox.Height);
900 void PresenterWindowManager::NotifyLayoutModeChange (void)
902 document::EventObject aEvent;
903 aEvent.Source = Reference<XInterface>(static_cast<XWeak*>(this));
905 LayoutListenerContainer aContainerCopy (maLayoutListeners);
906 LayoutListenerContainer::iterator iListener (aContainerCopy.begin());
907 LayoutListenerContainer::iterator iEnd (aContainerCopy.end());
908 for ( ; iListener!=iEnd; ++iListener)
910 if (iListener->is())
914 (*iListener)->notifyEvent(aEvent);
916 catch (lang::DisposedException&)
918 RemoveLayoutListener(*iListener);
920 catch (RuntimeException&)
927 void PresenterWindowManager::NotifyDisposing (void)
929 lang::EventObject aEvent;
930 aEvent.Source = static_cast<XWeak*>(this);
932 LayoutListenerContainer aContainer;
933 aContainer.swap(maLayoutListeners);
934 LayoutListenerContainer::iterator iListener (aContainer.begin());
935 LayoutListenerContainer::iterator iEnd (aContainer.end());
936 for ( ; iListener!=iEnd; ++iListener)
938 if (iListener->is())
942 (*iListener)->disposing(aEvent);
944 catch (lang::DisposedException&)
947 catch (RuntimeException&)
954 void PresenterWindowManager::UpdateWindowSize (const Reference<awt::XWindow>& rxBorderWindow)
956 PresenterPaneContainer::SharedPaneDescriptor pDescriptor (
957 mpPaneContainer->FindBorderWindow(rxBorderWindow));
958 if (pDescriptor.get() != NULL)
960 mxClipPolygon = NULL;
962 awt::Rectangle aParentBox = mxParentWindow->getPosSize();
963 awt::Rectangle aBorderBox (pDescriptor->mxBorderWindow->getPosSize());
965 if ( ! mbIsLayouting)
967 const double nWidth (aParentBox.Width);
968 const double nHeight (aParentBox.Height);
969 pDescriptor->mnLeft = double(aBorderBox.X) / nWidth;
970 pDescriptor->mnTop = double(aBorderBox.Y) / nHeight;
971 pDescriptor->mnRight = double(aBorderBox.X + aBorderBox.Width) / nWidth;
972 pDescriptor->mnBottom = double(aBorderBox.Y + aBorderBox.Height) / nHeight;
974 else
976 // This update of the window size was initiated by
977 // Layout(). Therefore the window size does not have to be
978 // updated.
981 // ToTop is called last because it may invalidate the iterator.
982 if ( ! mbIsLayouting)
983 mpPaneContainer->ToTop(pDescriptor);
987 void PresenterWindowManager::PaintBackground (const awt::Rectangle& rUpdateBox)
989 (void)rUpdateBox;
990 if ( ! mxParentWindow.is())
991 return;
993 Reference<rendering::XGraphicDevice> xDevice (mxParentCanvas->getDevice());
994 if ( ! xDevice.is())
995 return;
997 // Create a polygon for the background and for clipping.
998 Reference<rendering::XPolyPolygon2D> xBackgroundPolygon (
999 PresenterGeometryHelper::CreatePolygon(mxParentWindow->getPosSize(), xDevice));
1000 if ( ! mxClipPolygon.is())
1001 mxClipPolygon = CreateClipPolyPolygon();
1003 // Create View- and RenderState structs.
1004 const rendering::ViewState aViewState(
1005 geometry::AffineMatrix2D(1,0,0, 0,1,0),
1006 PresenterGeometryHelper::CreatePolygon(rUpdateBox, xDevice));
1007 rendering::RenderState aRenderState (
1008 geometry::AffineMatrix2D(1,0,0, 0,1,0),
1009 mxClipPolygon,
1010 Sequence<double>(4),
1011 rendering::CompositeOperation::SOURCE);
1013 // Paint the background.
1014 if (mpBackgroundBitmap.get() != NULL)
1016 ProvideBackgroundBitmap();
1018 if (mxScaledBackgroundBitmap.is())
1020 Sequence<rendering::Texture> aTextures (1);
1021 const geometry::IntegerSize2D aBitmapSize(mxScaledBackgroundBitmap->getSize());
1022 aTextures[0] = rendering::Texture (
1023 geometry::AffineMatrix2D(
1024 aBitmapSize.Width,0,0,
1025 0,aBitmapSize.Height,0),
1028 mxScaledBackgroundBitmap,
1029 NULL,
1030 NULL,
1031 rendering::StrokeAttributes(),
1032 rendering::TexturingMode::REPEAT,
1033 rendering::TexturingMode::REPEAT);
1035 mxParentCanvas->fillTexturedPolyPolygon(
1036 xBackgroundPolygon,
1037 aViewState,
1038 aRenderState,
1039 aTextures);
1041 else
1043 const util::Color aBackgroundColor (mpBackgroundBitmap->maReplacementColor);
1044 aRenderState.DeviceColor[0] = ((aBackgroundColor >> 16) & 0x0ff) / 255.0;
1045 aRenderState.DeviceColor[1] = ((aBackgroundColor >> 8) & 0x0ff) / 255.0;
1046 aRenderState.DeviceColor[2] = ((aBackgroundColor >> 0) & 0x0ff) / 255.0;
1047 aRenderState.DeviceColor[3] = ((aBackgroundColor >> 24) & 0x0ff) / 255.0;
1048 mxParentCanvas->fillPolyPolygon(
1049 xBackgroundPolygon,
1050 aViewState,
1051 aRenderState);
1056 void PresenterWindowManager::ProvideBackgroundBitmap (void)
1058 if ( ! mxScaledBackgroundBitmap.is())
1060 Reference<rendering::XBitmap> xBitmap (mpBackgroundBitmap->GetNormalBitmap());
1061 if (xBitmap.is())
1063 const bool bStretchVertical (mpBackgroundBitmap->meVerticalTexturingMode
1064 == PresenterBitmapDescriptor::Stretch);
1065 const bool bStretchHorizontal (mpBackgroundBitmap->meHorizontalTexturingMode
1066 == PresenterBitmapDescriptor::Stretch);
1067 if (bStretchHorizontal || bStretchVertical)
1069 geometry::RealSize2D aSize;
1070 if (bStretchVertical)
1071 aSize.Height = mxParentWindow->getPosSize().Height;
1072 else
1073 aSize.Height = xBitmap->getSize().Height;
1074 if (bStretchHorizontal)
1075 aSize.Width = mxParentWindow->getPosSize().Width;
1076 else
1077 aSize.Width = xBitmap->getSize().Width;
1078 mxScaledBackgroundBitmap = xBitmap->getScaledBitmap(aSize, sal_False);
1080 else
1082 mxScaledBackgroundBitmap
1083 = Reference<rendering::XBitmap>(xBitmap, UNO_QUERY);
1089 Reference<rendering::XPolyPolygon2D> PresenterWindowManager::CreateClipPolyPolygon (void) const
1091 // Create a clip polygon that includes the whole update area but has the
1092 // content windows as holes.
1093 const sal_Int32 nPaneCount (mpPaneContainer->maPanes.size());
1094 ::std::vector<awt::Rectangle> aRectangles;
1095 aRectangles.reserve(1+nPaneCount);
1096 aRectangles.push_back(mxParentWindow->getPosSize());
1097 PresenterPaneContainer::PaneList::const_iterator iPane;
1098 PresenterPaneContainer::PaneList::const_iterator iEnd (mpPaneContainer->maPanes.end());
1099 for (iPane=mpPaneContainer->maPanes.begin(); iPane!=iEnd; ++iPane)
1101 PresenterPaneContainer::SharedPaneDescriptor pDescriptor (*iPane);
1102 if ( ! pDescriptor->mbIsActive)
1103 continue;
1104 if ( ! pDescriptor->mbIsOpaque)
1105 continue;
1106 if ( ! pDescriptor->mxBorderWindow.is() || ! pDescriptor->mxContentWindow.is())
1107 continue;
1108 Reference<awt::XWindow2> xWindow (pDescriptor->mxBorderWindow, UNO_QUERY);
1109 if (xWindow.is() && ! xWindow->isVisible())
1110 continue;
1112 const awt::Rectangle aOuterBorderBox (pDescriptor->mxBorderWindow->getPosSize());
1113 awt::Rectangle aInnerBorderBox (pDescriptor->mxContentWindow->getPosSize());
1114 aInnerBorderBox.X += aOuterBorderBox.X;
1115 aInnerBorderBox.Y += aOuterBorderBox.Y;
1116 aRectangles.push_back(aInnerBorderBox);
1118 Reference<rendering::XPolyPolygon2D> xPolyPolygon (
1119 PresenterGeometryHelper::CreatePolygon(
1120 aRectangles,
1121 mxParentCanvas->getDevice()));
1122 if (xPolyPolygon.is())
1123 xPolyPolygon->setFillRule(rendering::FillRule_EVEN_ODD);
1124 return xPolyPolygon;
1127 void PresenterWindowManager::UpdateWindowList (void)
1129 #ifdef ENABLE_PANE_RESIZING
1132 OSL_ASSERT(mxComponentContext.is());
1134 Reference<lang::XComponent> xComponent (mxPaneBorderManager, UNO_QUERY);
1135 if (xComponent.is())
1136 xComponent->dispose();
1138 Reference<lang::XMultiComponentFactory> xFactory (mxComponentContext->getServiceManager());
1139 if (xFactory.is())
1141 Sequence<Any> aArguments (1 + mpPaneContainer->maPanes.size()*2);
1142 sal_Int32 nIndex (0);
1143 aArguments[nIndex++] = Any(mxParentWindow);
1144 for (sal_uInt32 nPaneIndex=0; nPaneIndex<mpPaneContainer->maPanes.size(); ++nPaneIndex)
1146 if ( ! mpPaneContainer->maPanes[nPaneIndex]->mbIsActive)
1147 continue;
1149 const Reference<awt::XWindow> xBorderWindow (
1150 mpPaneContainer->maPanes[nPaneIndex]->mxBorderWindow);
1151 const Reference<awt::XWindow> xContentWindow (
1152 mpPaneContainer->maPanes[nPaneIndex]->mxContentWindow);
1153 const Reference<awt::XWindow2> xBorderWindow2(xBorderWindow, UNO_QUERY);
1154 if (xBorderWindow.is()
1155 && xContentWindow.is()
1156 && ( ! xBorderWindow2.is() || xBorderWindow2->isVisible()))
1158 aArguments[nIndex++] = Any(xBorderWindow);
1159 aArguments[nIndex++] = Any(xContentWindow);
1163 aArguments.realloc(nIndex);
1164 rtl::Reference<PresenterPaneBorderManager> pManager (
1165 new PresenterPaneBorderManager (
1166 mxComponentContext,
1167 mpPresenterController));
1168 pManager->initialize(aArguments);
1169 mxPaneBorderManager = Reference<XInterface>(static_cast<XWeak*>(pManager.get()));
1172 catch (RuntimeException&)
1175 #endif
1178 void PresenterWindowManager::Invalidate (void)
1180 mpPresenterController->GetPaintManager()->Invalidate(mxParentWindow);
1182 void PresenterWindowManager::Update (void)
1184 mxClipPolygon = NULL;
1185 mbIsLayoutPending = true;
1187 UpdateWindowList();
1188 Invalidate();
1191 void PresenterWindowManager::ThrowIfDisposed (void) const
1192 throw (::com::sun::star::lang::DisposedException)
1194 if (rBHelper.bDisposed || rBHelper.bInDispose)
1196 throw lang::DisposedException (
1197 OUString( "PresenterWindowManager has already been disposed"),
1198 const_cast<uno::XWeak*>(static_cast<const uno::XWeak*>(this)));
1202 } } // end of namespace ::sdext::presenter
1204 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */