update dev300-m58
[ooovba.git] / sdext / source / presenter / PresenterToolBar.cxx
blob4f4a2cf010c1b1ad03e0e4a20a12aeb6968c6aad
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: PresenterToolBar.cxx,v $
11 * $Revision: 1.6 $
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 "PresenterToolBar.hxx"
37 #include "PresenterBitmapContainer.hxx"
38 #include "PresenterCanvasHelper.hxx"
39 #include "PresenterComponent.hxx"
40 #include "PresenterGeometryHelper.hxx"
41 #include "PresenterPaintManager.hxx"
42 #include "PresenterPaneBase.hxx"
43 #include "PresenterPaneFactory.hxx"
44 #include "PresenterTimer.hxx"
45 #include "PresenterWindowManager.hxx"
47 #include <cppuhelper/compbase2.hxx>
48 #include <com/sun/star/awt/FontDescriptor.hpp>
49 #include <com/sun/star/awt/PosSize.hpp>
50 #include <com/sun/star/awt/XWindowPeer.hpp>
51 #include <com/sun/star/deployment/XPackageInformationProvider.hpp>
52 #include <com/sun/star/drawing/framework/XControllerManager.hpp>
53 #include <com/sun/star/drawing/framework/XConfigurationController.hpp>
54 #include <com/sun/star/drawing/framework/XPane.hpp>
55 #include <com/sun/star/geometry/AffineMatrix2D.hpp>
56 #include <com/sun/star/lang/XServiceName.hpp>
57 #include <com/sun/star/rendering/CompositeOperation.hpp>
58 #include <com/sun/star/rendering/RenderState.hpp>
59 #include <com/sun/star/rendering/TextDirection.hpp>
60 #include <com/sun/star/rendering/ViewState.hpp>
61 #include <com/sun/star/rendering/XSpriteCanvas.hpp>
62 #include <com/sun/star/text/XTextRange.hpp>
63 #include <com/sun/star/util/Color.hpp>
64 #include <com/sun/star/util/XURLTransformer.hpp>
65 #include <rtl/ustrbuf.hxx>
66 #include <boost/bind.hpp>
67 #include <boost/function.hpp>
68 #include <boost/enable_shared_from_this.hpp>
69 #include <map>
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 #define A2S(pString) (::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(pString)))
78 namespace sdext { namespace presenter {
80 static const sal_Int32 gnGapSize (20);
81 static const sal_Int32 gnMinimalSeparatorSize (20);
82 static const sal_Int32 gnSeparatorInset (0);
84 namespace {
86 class Text
88 public:
89 Text (void);
90 Text (const Text& rText);
91 Text (
92 const OUString& rsText,
93 const PresenterTheme::SharedFontDescriptor& rpFont);
95 void SetText (const OUString& rsText);
96 OUString GetText (void) const;
97 PresenterTheme::SharedFontDescriptor GetFont (void) const;
99 void Paint (
100 const Reference<rendering::XCanvas>& rxCanvas,
101 const rendering::ViewState& rViewState,
102 const awt::Rectangle& rBoundingBox,
103 const awt::Point& rOffset);
105 geometry::RealRectangle2D GetBoundingBox (
106 const Reference<rendering::XCanvas>& rxCanvas);
108 private:
109 OUString msText;
110 PresenterTheme::SharedFontDescriptor mpFont;
113 class ElementMode
114 : private ::boost::noncopyable
116 public:
117 ElementMode (void);
119 SharedBitmapDescriptor mpIcon;
120 OUString msAction;
121 Text maText;
123 void ReadElementMode (
124 const Reference<beans::XPropertySet>& rxProperties,
125 const ::rtl::OUString& rsModeName,
126 ::boost::shared_ptr<ElementMode>& rpDefaultMode,
127 ::sdext::presenter::PresenterToolBar::Context& rContext);
129 typedef ::boost::shared_ptr<ElementMode> SharedElementMode;
131 } // end of anonymous namespace
134 class PresenterToolBar::Context
135 : private ::boost::noncopyable
137 public:
138 ::rtl::OUString msBasePath;
139 Reference<drawing::XPresenterHelper> mxPresenterHelper;
140 css::uno::Reference<css::rendering::XCanvas> mxCanvas;
146 //===== PresenterToolBar::Element =============================================
148 namespace {
149 typedef cppu::WeakComponentImplHelper2<
150 css::document::XEventListener,
151 css::frame::XStatusListener
152 > ElementInterfaceBase;
154 class Element
155 : private ::cppu::BaseMutex,
156 private ::boost::noncopyable,
157 public ElementInterfaceBase
159 public:
160 Element (const ::rtl::Reference<PresenterToolBar>& rpToolBar);
161 virtual ~Element (void);
163 virtual void SAL_CALL disposing (void);
165 virtual void SetModes (
166 const SharedElementMode& rpNormalMode,
167 const SharedElementMode& rpMouseOverMode,
168 const SharedElementMode& rpSelectedMode,
169 const SharedElementMode& rpDisabledMode);
170 virtual void CurrentSlideHasChanged (void);
171 virtual void SetLocation (const awt::Point& rLocation);
172 virtual void SetSize (const geometry::RealSize2D& rSize);
173 virtual void Paint (
174 const Reference<rendering::XCanvas>& rxCanvas,
175 const rendering::ViewState& rViewState) = 0;
176 awt::Size GetBoundingSize (
177 const Reference<rendering::XCanvas>& rxCanvas);
178 awt::Rectangle GetBoundingBox (void) const;
179 virtual bool SetState (const bool bIsOver, const bool bIsPressed);
180 virtual void Invalidate (const bool bSynchronous = true);
181 virtual bool IsOutside (const awt::Rectangle& rBox);
182 virtual bool IsFilling (void) const;
183 void UpdateState (void);
185 OUString GetAction (void) const;
187 // lang::XEventListener
189 virtual void SAL_CALL disposing (const css::lang::EventObject& rEvent)
190 throw(css::uno::RuntimeException);
192 // document::XEventListener
194 virtual void SAL_CALL notifyEvent (const css::document::EventObject& rEvent)
195 throw(css::uno::RuntimeException);
197 // frame::XStatusListener
199 virtual void SAL_CALL statusChanged (const css::frame::FeatureStateEvent& rEvent)
200 throw(css::uno::RuntimeException);
202 protected:
203 ::rtl::Reference<PresenterToolBar> mpToolBar;
204 awt::Point maLocation;
205 awt::Size maSize;
206 SharedElementMode mpNormal;
207 SharedElementMode mpMouseOver;
208 SharedElementMode mpSelected;
209 SharedElementMode mpDisabled;
210 SharedElementMode mpMode;
211 bool mbIsOver;
212 bool mbIsPressed;
213 bool mbIsSelected;
215 virtual awt::Size CreateBoundingSize (
216 const Reference<rendering::XCanvas>& rxCanvas) = 0;
218 bool IsEnabled (void) const;
219 void SetEnabledState (const bool bIsEnabled);
221 private:
222 bool mbIsEnabled;
225 } // end of anonymous namespace
228 class PresenterToolBar::ElementContainerPart
229 : public ::std::vector<rtl::Reference<Element> >
236 //===== Button ================================================================
238 namespace {
240 class Button : public Element
242 public:
243 static ::rtl::Reference<Element> Create (
244 const ::rtl::Reference<PresenterToolBar>& rpToolBar);
246 virtual ~Button (void);
247 virtual void SAL_CALL disposing (void);
249 virtual void Paint (
250 const Reference<rendering::XCanvas>& rxCanvas,
251 const rendering::ViewState& rViewState);
253 // lang::XEventListener
255 virtual void SAL_CALL disposing (const css::lang::EventObject& rEvent)
256 throw(css::uno::RuntimeException);
258 protected:
259 virtual awt::Size CreateBoundingSize (
260 const Reference<rendering::XCanvas>& rxCanvas);
262 private:
263 bool mbIsListenerRegistered;
265 Button (const ::rtl::Reference<PresenterToolBar>& rpToolBar);
266 void Initialize (void);
267 void PaintIcon (
268 const Reference<rendering::XCanvas>& rxCanvas,
269 const sal_Int32 nTextHeight,
270 const rendering::ViewState& rViewState);
271 PresenterBitmapDescriptor::Mode GetMode (void) const;
277 //===== Label =================================================================
279 class Label : public Element
281 public:
282 Label (const ::rtl::Reference<PresenterToolBar>& rpToolBar);
284 void SetText (const OUString& rsText);
285 virtual void Paint (
286 const Reference<rendering::XCanvas>& rxCanvas,
287 const rendering::ViewState& rViewState);
288 virtual bool SetState (const bool bIsOver, const bool bIsPressed);
290 protected:
291 virtual awt::Size CreateBoundingSize (
292 const Reference<rendering::XCanvas>& rxCanvas);
296 // Some specialized controls.
299 class ProgressLabel : public Label
301 public:
302 ProgressLabel (const ::rtl::Reference<PresenterToolBar>& rpToolBar);
303 virtual void CurrentSlideHasChanged (void);
306 class TimeFormatter
308 public:
309 TimeFormatter (void);
310 OUString FormatTime (const oslDateTime& rTime);
311 private:
312 bool mbIs24HourFormat;
313 bool mbIsAmPmFormat;
314 bool mbIsShowSeconds;
317 class TimeLabel : public Label
319 public:
320 void ConnectToTimer (void);
321 virtual void TimeHasChanged (const oslDateTime& rCurrentTime) = 0;
322 protected:
323 TimeLabel(const ::rtl::Reference<PresenterToolBar>& rpToolBar);
324 using Element::disposing;
325 virtual void SAL_CALL disposing (void);
326 private:
327 class Listener : public PresenterClockTimer::Listener
329 public:
330 Listener (const ::rtl::Reference<TimeLabel>& rxLabel)
331 : mxLabel(rxLabel) {}
332 virtual ~Listener (void) {}
333 virtual void TimeHasChanged (const oslDateTime& rCurrentTime)
334 { if (mxLabel.is()) mxLabel->TimeHasChanged(rCurrentTime); }
335 private:
336 ::rtl::Reference<TimeLabel> mxLabel;
338 ::boost::shared_ptr<PresenterClockTimer::Listener> mpListener;
341 class CurrentTimeLabel : public TimeLabel
343 public:
344 static ::rtl::Reference<Element> Create (
345 const ::rtl::Reference<PresenterToolBar>& rpToolBar);
346 virtual void SetModes (
347 const SharedElementMode& rpNormalMode,
348 const SharedElementMode& rpMouseOverMode,
349 const SharedElementMode& rpSelectedMode,
350 const SharedElementMode& rpDisabledMode);
351 private:
352 TimeFormatter maTimeFormatter;
353 CurrentTimeLabel (const ::rtl::Reference<PresenterToolBar>& rpToolBar);
354 virtual ~CurrentTimeLabel (void);
355 virtual void TimeHasChanged (const oslDateTime& rCurrentTime);
358 class PresentationTimeLabel : public TimeLabel
360 public:
361 static ::rtl::Reference<Element> Create (
362 const ::rtl::Reference<PresenterToolBar>& rpToolBar);
363 virtual void SetModes (
364 const SharedElementMode& rpNormalMode,
365 const SharedElementMode& rpMouseOverMode,
366 const SharedElementMode& rpSelectedMode,
367 const SharedElementMode& rpDisabledMode);
368 private:
369 TimeFormatter maTimeFormatter;
370 TimeValue maStartTimeValue;
371 PresentationTimeLabel (const ::rtl::Reference<PresenterToolBar>& rpToolBar);
372 virtual ~PresentationTimeLabel (void);
373 virtual void TimeHasChanged (const oslDateTime& rCurrentTime);
376 class VerticalSeparator : public Element
378 public:
379 explicit VerticalSeparator (const ::rtl::Reference<PresenterToolBar>& rpToolBar);
380 virtual void Paint (
381 const Reference<rendering::XCanvas>& rxCanvas,
382 const rendering::ViewState& rViewState);
383 virtual bool IsFilling (void) const;
385 protected:
386 virtual awt::Size CreateBoundingSize (
387 const Reference<rendering::XCanvas>& rxCanvas);
390 class HorizontalSeparator : public Element
392 public:
393 explicit HorizontalSeparator (const ::rtl::Reference<PresenterToolBar>& rpToolBar);
394 virtual void Paint (
395 const Reference<rendering::XCanvas>& rxCanvas,
396 const rendering::ViewState& rViewState);
397 virtual bool IsFilling (void) const;
399 protected:
400 virtual awt::Size CreateBoundingSize (
401 const Reference<rendering::XCanvas>& rxCanvas);
403 } // end of anonymous namespace
407 //===== PresenterToolBar ======================================================
409 PresenterToolBar::PresenterToolBar (
410 const Reference<XComponentContext>& rxContext,
411 const css::uno::Reference<css::awt::XWindow>& rxWindow,
412 const css::uno::Reference<css::rendering::XCanvas>& rxCanvas,
413 const ::rtl::Reference<PresenterController>& rpPresenterController,
414 const Anchor eAnchor)
415 : PresenterToolBarInterfaceBase(m_aMutex),
416 mxComponentContext(rxContext),
417 maElementContainer(),
418 mpCurrentContainerPart(),
419 mxWindow(rxWindow),
420 mxCanvas(rxCanvas),
421 mxSlideShowController(),
422 mxCurrentSlide(),
423 mpPresenterController(rpPresenterController),
424 mbIsLayoutPending(false),
425 meAnchor(eAnchor),
426 maBoundingBox(),
427 maMinimalSize()
434 void PresenterToolBar::Initialize (
435 const ::rtl::OUString& rsConfigurationPath)
439 CreateControls(rsConfigurationPath);
441 if (mxWindow.is())
443 mxWindow->addWindowListener(this);
444 mxWindow->addPaintListener(this);
445 mxWindow->addMouseListener(this);
446 mxWindow->addMouseMotionListener(this);
448 Reference<awt::XWindowPeer> xPeer (mxWindow, UNO_QUERY);
449 if (xPeer.is())
450 xPeer->setBackground(util::Color(0xff000000));
452 mxWindow->setVisible(sal_True);
455 mxSlideShowController = mpPresenterController->GetSlideShowController();
456 UpdateSlideNumber();
457 mbIsLayoutPending = true;
459 catch (RuntimeException&)
461 mpCurrentContainerPart.reset();
462 maElementContainer.clear();
463 throw;
470 PresenterToolBar::~PresenterToolBar (void)
477 void SAL_CALL PresenterToolBar::disposing (void)
479 if (mxWindow.is())
481 mxWindow->removeWindowListener(this);
482 mxWindow->removePaintListener(this);
483 mxWindow->removeMouseListener(this);
484 mxWindow->removeMouseMotionListener(this);
485 mxWindow = NULL;
488 // Dispose tool bar elements.
489 ElementContainer::iterator iPart (maElementContainer.begin());
490 ElementContainer::const_iterator iEnd (maElementContainer.end());
491 for ( ; iPart!=iEnd; ++iPart)
493 OSL_ASSERT(iPart->get()!=NULL);
494 ElementContainerPart::iterator iElement ((*iPart)->begin());
495 ElementContainerPart::const_iterator iPartEnd ((*iPart)->end());
496 for ( ; iElement!=iPartEnd; ++iElement)
498 if (iElement->get() != NULL)
500 ::rtl::Reference<Element> pElement (*iElement);
501 Reference<lang::XComponent> xComponent (
502 static_cast<XWeak*>(pElement.get()), UNO_QUERY);
503 if (xComponent.is())
504 xComponent->dispose();
509 mpCurrentContainerPart.reset();
510 maElementContainer.clear();
516 void PresenterToolBar::InvalidateArea (
517 const awt::Rectangle& rRepaintBox,
518 const bool bSynchronous)
520 mpPresenterController->GetPaintManager()->Invalidate(
521 mxWindow,
522 rRepaintBox,
523 bSynchronous);
529 sal_Int32 PresenterToolBar::GetCurrentSlideIndex (void)
531 if (mxSlideShowController.is())
532 return mxSlideShowController->getCurrentSlideIndex();
533 else
534 return -1;
540 sal_Int32 PresenterToolBar::GetSlideCount (void)
542 if (mxSlideShowController.is())
543 return mxSlideShowController->getSlideCount();
544 else
545 return 0;
551 void PresenterToolBar::RequestLayout (void)
553 mbIsLayoutPending = true;
555 mpPresenterController->GetPaintManager()->Invalidate(mxWindow);
561 geometry::RealSize2D PresenterToolBar::GetSize (void)
563 if (mbIsLayoutPending)
564 Layout(mxCanvas);
565 return geometry::RealSize2D(
566 maBoundingBox.X2 - maBoundingBox.X1,
567 maBoundingBox.Y2 - maBoundingBox.Y1);
573 geometry::RealSize2D PresenterToolBar::GetMinimalSize (void)
575 if (mbIsLayoutPending)
576 Layout(mxCanvas);
577 return maMinimalSize;
583 ::rtl::Reference<PresenterController> PresenterToolBar::GetPresenterController (void) const
585 return mpPresenterController;
591 Reference<awt::XWindow> PresenterToolBar::GetWindow (void) const
593 return mxWindow;
599 Reference<XComponentContext> PresenterToolBar::GetComponentContext (void) const
601 return mxComponentContext;
607 //----- lang::XEventListener -------------------------------------------------
609 void SAL_CALL PresenterToolBar::disposing (const lang::EventObject& rEventObject)
610 throw (RuntimeException)
612 if (rEventObject.Source == mxWindow)
613 mxWindow = NULL;
619 //----- XWindowListener -------------------------------------------------------
621 void SAL_CALL PresenterToolBar::windowResized (const awt::WindowEvent& rEvent)
622 throw (RuntimeException)
624 (void)rEvent;
625 mbIsLayoutPending = true;
631 void SAL_CALL PresenterToolBar::windowMoved (const awt::WindowEvent& rEvent)
632 throw (RuntimeException)
634 (void)rEvent;
640 void SAL_CALL PresenterToolBar::windowShown (const lang::EventObject& rEvent)
641 throw (RuntimeException)
643 (void)rEvent;
644 mbIsLayoutPending = true;
650 void SAL_CALL PresenterToolBar::windowHidden (const lang::EventObject& rEvent)
651 throw (RuntimeException)
653 (void)rEvent;
659 //----- XPaintListener --------------------------------------------------------
661 void SAL_CALL PresenterToolBar::windowPaint (const css::awt::PaintEvent& rEvent)
662 throw (RuntimeException)
664 if ( ! mxCanvas.is())
665 return;
667 if ( ! mbIsPresenterViewActive)
668 return;
670 const rendering::ViewState aViewState (
671 geometry::AffineMatrix2D(1,0,0, 0,1,0),
672 PresenterGeometryHelper::CreatePolygon(rEvent.UpdateRect, mxCanvas->getDevice()));
674 if (mbIsLayoutPending)
675 Layout(mxCanvas);
677 Paint(rEvent.UpdateRect, aViewState);
679 // Make the back buffer visible.
680 Reference<rendering::XSpriteCanvas> xSpriteCanvas (mxCanvas, UNO_QUERY);
681 if (xSpriteCanvas.is())
682 xSpriteCanvas->updateScreen(sal_False);
688 //----- XMouseListener --------------------------------------------------------
690 void SAL_CALL PresenterToolBar::mousePressed (const css::awt::MouseEvent& rEvent)
691 throw(css::uno::RuntimeException)
693 CheckMouseOver(rEvent, true, true);
699 void SAL_CALL PresenterToolBar::mouseReleased (const css::awt::MouseEvent& rEvent)
700 throw(css::uno::RuntimeException)
702 CheckMouseOver(rEvent, true);
708 void SAL_CALL PresenterToolBar::mouseEntered (const css::awt::MouseEvent& rEvent)
709 throw(css::uno::RuntimeException)
711 CheckMouseOver(rEvent, true);
717 void SAL_CALL PresenterToolBar::mouseExited (const css::awt::MouseEvent& rEvent)
718 throw(css::uno::RuntimeException)
720 CheckMouseOver(rEvent, false);
726 //----- XMouseMotionListener --------------------------------------------------
728 void SAL_CALL PresenterToolBar::mouseMoved (const css::awt::MouseEvent& rEvent)
729 throw (css::uno::RuntimeException)
731 ThrowIfDisposed();
733 CheckMouseOver(rEvent, true);
739 void SAL_CALL PresenterToolBar::mouseDragged (const css::awt::MouseEvent& rEvent)
740 throw (css::uno::RuntimeException)
742 ThrowIfDisposed();
743 (void)rEvent;
749 //----- XDrawView -------------------------------------------------------------
751 void SAL_CALL PresenterToolBar::setCurrentPage (const Reference<drawing::XDrawPage>& rxSlide)
752 throw (RuntimeException)
754 if (rxSlide != mxCurrentSlide)
756 mxCurrentSlide = rxSlide;
757 UpdateSlideNumber();
764 Reference<drawing::XDrawPage> SAL_CALL PresenterToolBar::getCurrentPage (void)
765 throw (RuntimeException)
767 return mxCurrentSlide;
773 //-----------------------------------------------------------------------------
775 void PresenterToolBar::CreateControls (
776 const ::rtl::OUString& rsConfigurationPath)
778 if ( ! mxWindow.is())
779 return;
781 // Expand the macro in the bitmap file names.
782 PresenterConfigurationAccess aConfiguration (
783 mxComponentContext,
784 OUString::createFromAscii("/org.openoffice.Office.extension.PresenterScreen/"),
785 PresenterConfigurationAccess::READ_ONLY);
787 const OUString sBasePath (PresenterComponent::GetBasePath(mxComponentContext));
789 mpCurrentContainerPart.reset(new ElementContainerPart());
790 maElementContainer.clear();
791 maElementContainer.push_back(mpCurrentContainerPart);
793 Reference<container::XHierarchicalNameAccess> xToolBarNode (
794 aConfiguration.GetConfigurationNode(rsConfigurationPath),
795 UNO_QUERY);
796 if (xToolBarNode.is())
798 Reference<container::XNameAccess> xEntries (
799 PresenterConfigurationAccess::GetConfigurationNode(xToolBarNode, A2S("Entries")),
800 UNO_QUERY);
801 Context aContext;
802 aContext.msBasePath = sBasePath;
803 aContext.mxPresenterHelper = mpPresenterController->GetPresenterHelper();
804 aContext.mxCanvas = mxCanvas;
805 if (xEntries.is()
806 && aContext.mxPresenterHelper.is()
807 && aContext.mxCanvas.is())
809 PresenterConfigurationAccess::ForAll(
810 xEntries,
811 ::boost::bind(&PresenterToolBar::ProcessEntry, this, _2, ::boost::ref(aContext)));
819 void PresenterToolBar::ProcessEntry (
820 const Reference<beans::XPropertySet>& rxProperties,
821 Context& rContext)
823 if ( ! rxProperties.is())
824 return;
826 // Type has to be present.
827 OUString sType;
828 if ( ! (PresenterConfigurationAccess::GetProperty(rxProperties, A2S("Type")) >>= sType))
829 return;
831 OUString sName;
832 PresenterConfigurationAccess::GetProperty(rxProperties, A2S("Name")) >>= sName;
834 // Read mode specific values.
835 SharedElementMode pNormalMode (new ElementMode());
836 SharedElementMode pMouseOverMode (new ElementMode());
837 SharedElementMode pSelectedMode (new ElementMode());
838 SharedElementMode pDisabledMode (new ElementMode());
839 pNormalMode->ReadElementMode(rxProperties, A2S("Normal"), pNormalMode, rContext);
840 pMouseOverMode->ReadElementMode(rxProperties, A2S("MouseOver"), pNormalMode, rContext);
841 pSelectedMode->ReadElementMode(rxProperties, A2S("Selected"), pNormalMode, rContext);
842 pDisabledMode->ReadElementMode(rxProperties, A2S("Disabled"), pNormalMode, rContext);
844 // Create new element.
845 ::rtl::Reference<Element> pElement;
846 if (sType.equalsAscii("Button"))
847 pElement = Button::Create(this);
848 else if (sType.equalsAscii("CurrentTimeLabel"))
849 pElement = CurrentTimeLabel::Create(this);
850 else if (sType.equalsAscii("PresentationTimeLabel"))
851 pElement = PresentationTimeLabel::Create(this);
852 else if (sType.equalsAscii("VerticalSeparator"))
853 pElement = ::rtl::Reference<Element>(new VerticalSeparator(this));
854 else if (sType.equalsAscii("HorizontalSeparator"))
855 pElement = ::rtl::Reference<Element>(new HorizontalSeparator(this));
856 else if (sType.equalsAscii("Label"))
857 pElement = ::rtl::Reference<Element>(new Label(this));
858 else if (sType.equalsAscii("ChangeOrientation"))
860 mpCurrentContainerPart.reset(new ElementContainerPart());
861 maElementContainer.push_back(mpCurrentContainerPart);
862 return;
864 if (pElement.is())
866 pElement->SetModes( pNormalMode, pMouseOverMode, pSelectedMode, pDisabledMode);
867 pElement->UpdateState();
868 if (mpCurrentContainerPart.get() != NULL)
869 mpCurrentContainerPart->push_back(pElement);
876 void PresenterToolBar::Layout (
877 const Reference<rendering::XCanvas>& rxCanvas)
879 if (maElementContainer.size() == 0)
880 return;
882 mbIsLayoutPending = false;
884 const awt::Rectangle aWindowBox (mxWindow->getPosSize());
885 ElementContainer::iterator iPart;
886 ElementContainer::iterator iEnd (maElementContainer.end());
887 ::std::vector<geometry::RealSize2D> aPartSizes (maElementContainer.size());
888 geometry::RealSize2D aTotalSize (0,0);
889 bool bIsHorizontal (true);
890 sal_Int32 nIndex;
891 double nTotalHorizontalGap (0);
892 sal_Int32 nGapCount (0);
893 for (iPart=maElementContainer.begin(),nIndex=0; iPart!=iEnd; ++iPart,++nIndex)
895 geometry::RealSize2D aSize (CalculatePartSize(rxCanvas, *iPart, bIsHorizontal));
897 // Remember the size of each part for later.
898 aPartSizes[nIndex] = aSize;
900 // Add gaps between elements.
901 if ((*iPart)->size()>1 && bIsHorizontal)
903 nTotalHorizontalGap += ((*iPart)->size() - 1) * gnGapSize;
904 nGapCount += (*iPart)->size()-1;
907 // Orientation changes for each part.
908 bIsHorizontal = !bIsHorizontal;
909 // Width is accumulated.
910 aTotalSize.Width += aSize.Width;
911 // Height is the maximum height of all parts.
912 aTotalSize.Height = ::std::max(aTotalSize.Height, aSize.Height);
914 // Add gaps between parts.
915 if (maElementContainer.size() > 1)
917 nTotalHorizontalGap += (maElementContainer.size() - 1) * gnGapSize;
918 nGapCount += maElementContainer.size()-1;
921 // Calculate the minimal size so that the window size of the tool bar
922 // can be adapted accordingly.
923 maMinimalSize = aTotalSize;
924 maMinimalSize.Width += nTotalHorizontalGap;
926 // Calculate the gaps between elements.
927 double nGapWidth (0);
928 if (nGapCount > 0)
930 if (aTotalSize.Width + nTotalHorizontalGap > aWindowBox.Width)
931 nTotalHorizontalGap = aWindowBox.Width - aTotalSize.Width;
932 nGapWidth = nTotalHorizontalGap / nGapCount;
935 // Determine the location of the left edge.
936 double nX (0);
937 switch (meAnchor)
939 case Left : nX = 0; break;
940 case Center: nX = (aWindowBox.Width - aTotalSize.Width - nTotalHorizontalGap) / 2; break;
941 case Right: nX = aWindowBox.Width - aTotalSize.Width - nTotalHorizontalGap; break;
944 // Place the parts.
945 double nY ((aWindowBox.Height - aTotalSize.Height) / 2);
946 bIsHorizontal = true;
948 maBoundingBox.X1 = nX;
949 maBoundingBox.Y1 = nY;
950 maBoundingBox.X2 = nX + aTotalSize.Width + nTotalHorizontalGap;
951 maBoundingBox.Y2 = nY + aTotalSize.Height;
953 for (iPart=maElementContainer.begin(), nIndex=0; iPart!=iEnd; ++iPart,++nIndex)
955 geometry::RealRectangle2D aBoundingBox(
956 nX, nY,
957 nX+aPartSizes[nIndex].Width, nY+aTotalSize.Height);
959 // Add space for gaps between elements.
960 if ((*iPart)->size() > 1)
961 if (bIsHorizontal)
962 aBoundingBox.X2 += ((*iPart)->size()-1) * nGapWidth;
964 LayoutPart(rxCanvas, *iPart, aBoundingBox, aPartSizes[nIndex], bIsHorizontal);
965 bIsHorizontal = !bIsHorizontal;
966 nX += aBoundingBox.X2 - aBoundingBox.X1 + nGapWidth;
969 // The whole window has to be repainted.
970 mpPresenterController->GetPaintManager()->Invalidate(mxWindow);
976 geometry::RealSize2D PresenterToolBar::CalculatePartSize (
977 const Reference<rendering::XCanvas>& rxCanvas,
978 const SharedElementContainerPart& rpPart,
979 const bool bIsHorizontal)
981 geometry::RealSize2D aTotalSize (0,0);
983 if (mxWindow.is())
985 const awt::Rectangle aWindowBox (mxWindow->getPosSize());
987 // Calculate the summed width of all elements.
988 ElementContainerPart::const_iterator iElement;
989 for (iElement=rpPart->begin(); iElement!=rpPart->end(); ++iElement)
991 if (iElement->get() == NULL)
992 continue;
994 const awt::Size aBSize ((*iElement)->GetBoundingSize(rxCanvas));
995 if (bIsHorizontal)
997 aTotalSize.Width += aBSize.Width;
998 if (aBSize.Height > aTotalSize.Height)
999 aTotalSize.Height = aBSize.Height;
1001 else
1003 aTotalSize.Height += aBSize.Height;
1004 if (aBSize.Width > aTotalSize.Width)
1005 aTotalSize.Width = aBSize.Width;
1009 return aTotalSize;
1015 void PresenterToolBar::LayoutPart (
1016 const Reference<rendering::XCanvas>& rxCanvas,
1017 const SharedElementContainerPart& rpPart,
1018 const geometry::RealRectangle2D& rBoundingBox,
1019 const geometry::RealSize2D& rPartSize,
1020 const bool bIsHorizontal)
1022 double nGap (0);
1023 if (rpPart->size() > 1)
1025 if (bIsHorizontal)
1026 nGap = (rBoundingBox.X2 - rBoundingBox.X1 - rPartSize.Width) / (rpPart->size()-1);
1027 else
1028 nGap = (rBoundingBox.Y2 - rBoundingBox.Y1 - rPartSize.Height) / (rpPart->size()-1);
1031 // Place the elements.
1032 double nX (rBoundingBox.X1);
1033 double nY (rBoundingBox.Y1);
1035 ElementContainerPart::const_iterator iElement;
1036 ElementContainerPart::const_iterator iEnd (rpPart->end());
1037 for (iElement=rpPart->begin(); iElement!=iEnd; ++iElement)
1039 if (iElement->get() == NULL)
1040 continue;
1042 const awt::Size aElementSize ((*iElement)->GetBoundingSize(rxCanvas));
1043 if (bIsHorizontal)
1045 if ((*iElement)->IsFilling())
1047 nY = rBoundingBox.Y1;
1048 (*iElement)->SetSize(geometry::RealSize2D(aElementSize.Width, rBoundingBox.Y2 - rBoundingBox.Y1));
1050 else
1051 nY = rBoundingBox.Y1 + (rBoundingBox.Y2-rBoundingBox.Y1 - aElementSize.Height) / 2;
1052 (*iElement)->SetLocation(awt::Point(sal_Int32(0.5 + nX), sal_Int32(0.5 + nY)));
1053 nX += aElementSize.Width + nGap;
1055 else
1057 if ((*iElement)->IsFilling())
1059 nX = rBoundingBox.X1;
1060 (*iElement)->SetSize(geometry::RealSize2D(rBoundingBox.X2 - rBoundingBox.X1, aElementSize.Height));
1062 else
1063 nX = rBoundingBox.X1 + (rBoundingBox.X2-rBoundingBox.X1 - aElementSize.Width) / 2;
1064 (*iElement)->SetLocation(awt::Point(sal_Int32(0.5 + nX), sal_Int32(0.5 + nY)));
1065 nY += aElementSize.Height + nGap;
1073 void PresenterToolBar::Paint (
1074 const awt::Rectangle& rUpdateBox,
1075 const rendering::ViewState& rViewState)
1077 OSL_ASSERT(mxCanvas.is());
1079 ElementContainer::iterator iPart;
1080 ElementContainer::const_iterator iEnd (maElementContainer.end());
1081 for (iPart=maElementContainer.begin(); iPart!=iEnd; ++iPart)
1083 ElementContainerPart::iterator iElement;
1084 ElementContainerPart::const_iterator iPartEnd ((*iPart)->end());
1085 for (iElement=(*iPart)->begin(); iElement!=iPartEnd; ++iElement)
1087 if (iElement->get() != NULL)
1089 if ( ! (*iElement)->IsOutside(rUpdateBox))
1090 (*iElement)->Paint(mxCanvas, rViewState);
1099 void PresenterToolBar::UpdateSlideNumber (void)
1101 if( mxSlideShowController.is() )
1103 ElementContainer::iterator iPart;
1104 ElementContainer::const_iterator iEnd (maElementContainer.end());
1105 for (iPart=maElementContainer.begin(); iPart!=iEnd; ++iPart)
1107 ElementContainerPart::iterator iElement;
1108 ElementContainerPart::const_iterator iPartEnd ((*iPart)->end());
1109 for (iElement=(*iPart)->begin(); iElement!=iPartEnd; ++iElement)
1111 if (iElement->get() != NULL)
1112 (*iElement)->CurrentSlideHasChanged();
1121 void PresenterToolBar::CheckMouseOver (
1122 const css::awt::MouseEvent& rEvent,
1123 const bool bOverWindow,
1124 const bool bMouseDown)
1126 ElementContainer::iterator iPart;
1127 ElementContainer::const_iterator iEnd (maElementContainer.end());
1128 for (iPart=maElementContainer.begin(); iPart!=iEnd; ++iPart)
1130 ElementContainerPart::iterator iElement;
1131 ElementContainerPart::const_iterator iPartEnd ((*iPart)->end());
1132 for (iElement=(*iPart)->begin(); iElement!=iPartEnd; ++iElement)
1134 if (iElement->get() == NULL)
1135 continue;
1137 awt::Rectangle aBox ((*iElement)->GetBoundingBox());
1138 const bool bIsOver = bOverWindow
1139 && aBox.X <= rEvent.X
1140 && aBox.Width+aBox.X-1 >= rEvent.X
1141 && aBox.Y <= rEvent.Y
1142 && aBox.Height+aBox.Y-1 >= rEvent.Y;
1143 (*iElement)->SetState(
1144 bIsOver,
1145 bIsOver && rEvent.Buttons!=0 && bMouseDown && rEvent.ClickCount>0);
1153 void PresenterToolBar::ThrowIfDisposed (void) const
1154 throw (::com::sun::star::lang::DisposedException)
1156 if (rBHelper.bDisposed || rBHelper.bInDispose)
1158 throw lang::DisposedException (
1159 OUString(RTL_CONSTASCII_USTRINGPARAM(
1160 "PresenterToolBar has already been disposed")),
1161 const_cast<uno::XWeak*>(static_cast<const uno::XWeak*>(this)));
1168 //===== PresenterToolBarView ==================================================
1170 PresenterToolBarView::PresenterToolBarView (
1171 const Reference<XComponentContext>& rxContext,
1172 const Reference<XResourceId>& rxViewId,
1173 const Reference<frame::XController>& rxController,
1174 const ::rtl::Reference<PresenterController>& rpPresenterController)
1175 : PresenterToolBarViewInterfaceBase(m_aMutex),
1176 mxPane(),
1177 mxViewId(rxViewId),
1178 mxWindow(),
1179 mxCanvas(),
1180 mpPresenterController(rpPresenterController),
1181 mxSlideShowController(rpPresenterController->GetSlideShowController()),
1182 mpToolBar()
1186 Reference<XControllerManager> xCM (rxController, UNO_QUERY_THROW);
1187 Reference<XConfigurationController> xCC(xCM->getConfigurationController(),UNO_QUERY_THROW);
1188 mxPane = Reference<XPane>(xCC->getResource(rxViewId->getAnchor()), UNO_QUERY_THROW);
1190 mxWindow = mxPane->getWindow();
1191 mxCanvas = mxPane->getCanvas();
1193 mpToolBar = new PresenterToolBar(
1194 rxContext,
1195 mxWindow,
1196 mxCanvas,
1197 rpPresenterController,
1198 PresenterToolBar::Center);
1199 mpToolBar->Initialize(A2S("PresenterScreenSettings/ToolBars/ToolBar"));
1201 if (mxWindow.is())
1203 mxWindow->addPaintListener(this);
1205 Reference<awt::XWindowPeer> xPeer (mxWindow, UNO_QUERY);
1206 if (xPeer.is())
1207 xPeer->setBackground(util::Color(0xff000000));
1209 mxWindow->setVisible(sal_True);
1212 catch (RuntimeException&)
1214 mxViewId = NULL;
1215 throw;
1222 PresenterToolBarView::~PresenterToolBarView (void)
1229 void SAL_CALL PresenterToolBarView::disposing (void)
1231 Reference<lang::XComponent> xComponent (static_cast<XWeak*>(mpToolBar.get()), UNO_QUERY);
1232 mpToolBar = NULL;
1233 if (xComponent.is())
1234 xComponent->dispose();
1236 if (mxWindow.is())
1238 mxWindow->removePaintListener(this);
1239 mxWindow = NULL;
1241 mxCanvas = NULL;
1242 mxViewId = NULL;
1243 mxPane = NULL;
1244 mpPresenterController = NULL;
1245 mxSlideShowController = NULL;
1252 ::rtl::Reference<PresenterToolBar> PresenterToolBarView::GetPresenterToolBar (void) const
1254 return mpToolBar;
1260 //----- XPaintListener --------------------------------------------------------
1262 void SAL_CALL PresenterToolBarView::windowPaint (const css::awt::PaintEvent& rEvent)
1263 throw (RuntimeException)
1265 awt::Rectangle aWindowBox (mxWindow->getPosSize());
1266 mpPresenterController->GetCanvasHelper()->Paint(
1267 mpPresenterController->GetViewBackground(mxViewId->getResourceURL()),
1268 mxCanvas,
1269 rEvent.UpdateRect,
1270 awt::Rectangle(0,0,aWindowBox.Width, aWindowBox.Height),
1271 awt::Rectangle());
1277 //----- lang::XEventListener -------------------------------------------------
1279 void SAL_CALL PresenterToolBarView::disposing (const lang::EventObject& rEventObject)
1280 throw (RuntimeException)
1282 if (rEventObject.Source == mxWindow)
1283 mxWindow = NULL;
1289 //----- XResourceId -----------------------------------------------------------
1291 Reference<XResourceId> SAL_CALL PresenterToolBarView::getResourceId (void)
1292 throw (RuntimeException)
1294 return mxViewId;
1300 sal_Bool SAL_CALL PresenterToolBarView::isAnchorOnly (void)
1301 throw (RuntimeException)
1303 return false;
1309 //----- XDrawView -------------------------------------------------------------
1311 void SAL_CALL PresenterToolBarView::setCurrentPage (const Reference<drawing::XDrawPage>& rxSlide)
1312 throw (RuntimeException)
1314 Reference<drawing::XDrawView> xToolBar (static_cast<XWeak*>(mpToolBar.get()), UNO_QUERY);
1315 if (xToolBar.is())
1316 xToolBar->setCurrentPage(rxSlide);
1322 Reference<drawing::XDrawPage> SAL_CALL PresenterToolBarView::getCurrentPage (void)
1323 throw (RuntimeException)
1325 return NULL;
1331 //-----------------------------------------------------------------------------
1333 void PresenterToolBarView::ThrowIfDisposed (void) const
1334 throw (::com::sun::star::lang::DisposedException)
1336 if (rBHelper.bDisposed || rBHelper.bInDispose)
1338 throw lang::DisposedException (
1339 OUString(RTL_CONSTASCII_USTRINGPARAM(
1340 "PresenterToolBarView has already been disposed")),
1341 const_cast<uno::XWeak*>(static_cast<const uno::XWeak*>(this)));
1348 //===== PresenterToolBar::Element =============================================
1350 namespace {
1352 Element::Element (
1353 const ::rtl::Reference<PresenterToolBar>& rpToolBar)
1354 : ElementInterfaceBase(m_aMutex),
1355 mpToolBar(rpToolBar),
1356 maLocation(),
1357 maSize(),
1358 mpNormal(),
1359 mpMouseOver(),
1360 mpSelected(),
1361 mpDisabled(),
1362 mpMode(),
1363 mbIsOver(false),
1364 mbIsPressed(false),
1365 mbIsSelected(false),
1366 mbIsEnabled(true)
1368 if (mpToolBar.get() != NULL)
1370 OSL_ASSERT(mpToolBar->GetPresenterController().is());
1371 OSL_ASSERT(mpToolBar->GetPresenterController()->GetWindowManager().is());
1378 Element::~Element (void)
1385 void Element::SetModes (
1386 const SharedElementMode& rpNormalMode,
1387 const SharedElementMode& rpMouseOverMode,
1388 const SharedElementMode& rpSelectedMode,
1389 const SharedElementMode& rpDisabledMode)
1391 mpNormal = rpNormalMode;
1392 mpMouseOver = rpMouseOverMode;
1393 mpSelected = rpSelectedMode;
1394 mpDisabled = rpDisabledMode;
1395 mpMode = rpNormalMode;
1401 void Element::disposing (void)
1408 awt::Size Element::GetBoundingSize (
1409 const Reference<rendering::XCanvas>& rxCanvas)
1411 maSize = CreateBoundingSize(rxCanvas);
1412 return maSize;
1418 awt::Rectangle Element::GetBoundingBox (void) const
1420 return awt::Rectangle(maLocation.X,maLocation.Y, maSize.Width, maSize.Height);
1426 void Element::CurrentSlideHasChanged (void)
1428 UpdateState();
1434 void Element::SetLocation (const awt::Point& rLocation)
1436 maLocation = rLocation;
1441 void Element::SetSize (const geometry::RealSize2D& rSize)
1443 maSize = awt::Size(sal_Int32(0.5+rSize.Width), sal_Int32(0.5+rSize.Height));
1449 bool Element::SetState (
1450 const bool bIsOver,
1451 const bool bIsPressed)
1453 bool bModified (mbIsOver != bIsOver || mbIsPressed != bIsPressed);
1454 bool bClicked (mbIsPressed && bIsOver && ! bIsPressed);
1456 mbIsOver = bIsOver;
1457 mbIsPressed = bIsPressed;
1459 // When the element is disabled then ignore mouse over or selection.
1460 // When the element is selected then ignore mouse over.
1461 if ( ! mbIsEnabled)
1462 mpMode = mpDisabled;
1463 else if (mbIsSelected)
1464 mpMode = mpSelected;
1465 else if (mbIsOver)
1466 mpMode = mpMouseOver;
1467 else
1468 mpMode = mpNormal;
1470 if (bClicked && mbIsEnabled)
1472 if (mpMode.get() != NULL)
1476 if (mpMode->msAction.getLength() <= 0)
1477 break;
1479 if (mpToolBar.get() == NULL)
1480 break;
1482 if (mpToolBar->GetPresenterController().get() == NULL)
1483 break;
1485 mpToolBar->GetPresenterController()->DispatchUnoCommand(mpMode->msAction);
1486 mpToolBar->RequestLayout();
1488 while (false);
1492 else if (bModified)
1494 Invalidate();
1497 return bModified;
1503 void Element::Invalidate (const bool bSynchronous)
1505 OSL_ASSERT(mpToolBar.is());
1506 mpToolBar->InvalidateArea(GetBoundingBox(), bSynchronous);
1512 bool Element::IsOutside (const awt::Rectangle& rBox)
1514 if (rBox.X >= maLocation.X+maSize.Width)
1515 return true;
1516 else if (rBox.Y >= maLocation.Y+maSize.Height)
1517 return true;
1518 else if (maLocation.X >= rBox.X+rBox.Width)
1519 return true;
1520 else if (maLocation.Y >= rBox.Y+rBox.Height)
1521 return true;
1522 else
1523 return false;
1528 bool Element::IsEnabled (void) const
1530 return mbIsEnabled;
1536 void Element::SetEnabledState (const bool bIsEnabled)
1538 mbIsEnabled = bIsEnabled;
1544 bool Element::IsFilling (void) const
1546 return false;
1552 void Element::UpdateState (void)
1554 OSL_ASSERT(mpToolBar.get() != NULL);
1555 OSL_ASSERT(mpToolBar->GetPresenterController().get() != NULL);
1557 if (mpMode.get() == NULL)
1558 return;
1560 util::URL aURL (mpToolBar->GetPresenterController()->CreateURLFromString(mpMode->msAction));
1561 Reference<frame::XDispatch> xDispatch (mpToolBar->GetPresenterController()->GetDispatch(aURL));
1562 if (xDispatch.is())
1564 xDispatch->addStatusListener(this, aURL);
1565 xDispatch->removeStatusListener(this, aURL);
1572 //----- lang::XEventListener --------------------------------------------------
1574 void SAL_CALL Element::disposing (const css::lang::EventObject& rEvent)
1575 throw(css::uno::RuntimeException)
1577 (void)rEvent;
1583 //----- document::XEventListener ----------------------------------------------
1585 void SAL_CALL Element::notifyEvent (const css::document::EventObject& rEvent)
1586 throw(css::uno::RuntimeException)
1588 (void)rEvent;
1589 UpdateState();
1595 //----- frame::XStatusListener ------------------------------------------------
1597 void SAL_CALL Element::statusChanged (const css::frame::FeatureStateEvent& rEvent)
1598 throw(css::uno::RuntimeException)
1600 bool bIsSelected (mbIsSelected);
1601 bool bIsEnabled (rEvent.IsEnabled);
1602 rEvent.State >>= bIsSelected;
1604 if (bIsSelected != mbIsSelected || bIsEnabled != mbIsEnabled)
1606 mbIsEnabled = bIsEnabled;
1607 mbIsSelected = bIsSelected;
1608 SetState(mbIsOver, mbIsPressed);
1609 mpToolBar->RequestLayout();
1613 } // end of anonymous namespace
1618 //===== ElementMode ===========================================================
1620 namespace {
1622 ElementMode::ElementMode (void)
1623 : mpIcon(),
1624 msAction(),
1625 maText()
1632 void ElementMode::ReadElementMode (
1633 const Reference<beans::XPropertySet>& rxElementProperties,
1634 const OUString& rsModeName,
1635 ::boost::shared_ptr<ElementMode>& rpDefaultMode,
1636 ::sdext::presenter::PresenterToolBar::Context& rContext)
1640 Reference<container::XHierarchicalNameAccess> xNode (
1641 PresenterConfigurationAccess::GetProperty(rxElementProperties, rsModeName),
1642 UNO_QUERY);
1643 Reference<beans::XPropertySet> xProperties (
1644 PresenterConfigurationAccess::GetNodeProperties(xNode, OUString()));
1645 if ( ! xProperties.is() && rpDefaultMode.get()!=NULL)
1647 // The mode is not specified. Use the given, possibly empty,
1648 // default mode instead.
1649 mpIcon = rpDefaultMode->mpIcon;
1650 msAction = rpDefaultMode->msAction;
1651 maText = rpDefaultMode->maText;
1654 // Read action.
1655 if ( ! (PresenterConfigurationAccess::GetProperty(xProperties, A2S("Action")) >>= msAction))
1656 if (rpDefaultMode.get()!=NULL)
1657 msAction = rpDefaultMode->msAction;
1659 // Read text and font
1660 OUString sText (rpDefaultMode.get()!=NULL ? rpDefaultMode->maText.GetText() : OUString());
1661 PresenterConfigurationAccess::GetProperty(xProperties, A2S("Text")) >>= sText;
1662 Reference<container::XHierarchicalNameAccess> xFontNode (
1663 PresenterConfigurationAccess::GetProperty(xProperties, A2S("Font")), UNO_QUERY);
1664 PresenterTheme::SharedFontDescriptor pFont (PresenterTheme::ReadFont(
1665 xFontNode,
1666 A2S(""),
1667 rpDefaultMode.get()!=NULL
1668 ? rpDefaultMode->maText.GetFont()
1669 : PresenterTheme::SharedFontDescriptor()));
1670 maText = Text(sText,pFont);
1672 // Read bitmaps to display as icons.
1673 Reference<container::XHierarchicalNameAccess> xIconNode (
1674 PresenterConfigurationAccess::GetProperty(xProperties, A2S("Icon")), UNO_QUERY);
1675 mpIcon = PresenterBitmapContainer::LoadBitmap(
1676 xIconNode,
1677 A2S(""),
1678 rContext.mxPresenterHelper,
1679 rContext.msBasePath,
1680 rContext.mxCanvas,
1681 rpDefaultMode.get()!=NULL ? rpDefaultMode->mpIcon : SharedBitmapDescriptor());
1683 catch(Exception&)
1685 OSL_ASSERT(false);
1689 } // end of anonymous namespace
1694 //===== Button ================================================================
1696 namespace {
1698 ::rtl::Reference<Element> Button::Create (
1699 const ::rtl::Reference<PresenterToolBar>& rpToolBar)
1701 ::rtl::Reference<Button> pElement (new Button(rpToolBar));
1702 pElement->Initialize();
1703 return ::rtl::Reference<Element>(pElement.get());
1709 Button::Button (
1710 const ::rtl::Reference<PresenterToolBar>& rpToolBar)
1711 : Element(rpToolBar),
1712 mbIsListenerRegistered(false)
1714 OSL_ASSERT(mpToolBar.get() != NULL);
1715 OSL_ASSERT(mpToolBar->GetPresenterController().is());
1716 OSL_ASSERT(mpToolBar->GetPresenterController()->GetWindowManager().is());
1722 Button::~Button (void)
1729 void Button::Initialize (void)
1731 mpToolBar->GetPresenterController()->GetWindowManager()->AddLayoutListener(this);
1732 mbIsListenerRegistered = true;
1738 void Button::disposing (void)
1740 OSL_ASSERT(mpToolBar.get() != NULL);
1741 if (mpToolBar.get() != NULL
1742 && mbIsListenerRegistered)
1744 OSL_ASSERT(mpToolBar->GetPresenterController().is());
1745 OSL_ASSERT(mpToolBar->GetPresenterController()->GetWindowManager().is());
1747 mbIsListenerRegistered = false;
1748 mpToolBar->GetPresenterController()->GetWindowManager()->RemoveLayoutListener(this);
1750 Element::disposing();
1756 void Button::Paint (
1757 const Reference<rendering::XCanvas>& rxCanvas,
1758 const rendering::ViewState& rViewState)
1760 OSL_ASSERT(rxCanvas.is());
1762 if (mpMode.get() == NULL)
1763 return;
1765 if (mpMode->mpIcon.get() == NULL)
1766 return;
1768 geometry::RealRectangle2D aTextBBox (mpMode->maText.GetBoundingBox(rxCanvas));
1769 sal_Int32 nTextHeight (sal::static_int_cast<sal_Int32>(0.5 + aTextBBox.Y2 - aTextBBox.Y1));
1771 PaintIcon(rxCanvas, nTextHeight, rViewState);
1772 awt::Point aOffset(0,0);
1773 if ( ! IsEnabled())
1774 if (mpMode->mpIcon.get() != NULL)
1776 Reference<rendering::XBitmap> xBitmap (mpMode->mpIcon->GetNormalBitmap());
1777 if (xBitmap.is())
1778 aOffset.Y = xBitmap->getSize().Height;
1780 mpMode->maText.Paint(rxCanvas, rViewState, GetBoundingBox(), aOffset);
1786 awt::Size Button::CreateBoundingSize (
1787 const Reference<rendering::XCanvas>& rxCanvas)
1789 if (mpMode.get() == NULL)
1790 return awt::Size();
1792 geometry::RealRectangle2D aTextBBox (mpMode->maText.GetBoundingBox(rxCanvas));
1793 const sal_Int32 nGap (5);
1794 sal_Int32 nTextHeight (sal::static_int_cast<sal_Int32>(0.5 + aTextBBox.Y2 - aTextBBox.Y1));
1795 sal_Int32 nTextWidth (sal::static_int_cast<sal_Int32>(0.5 + aTextBBox.X2 - aTextBBox.X1));
1796 Reference<rendering::XBitmap> xBitmap;
1797 if (mpMode->mpIcon.get() != NULL)
1798 xBitmap = mpMode->mpIcon->GetNormalBitmap();
1799 if (xBitmap.is())
1801 geometry::IntegerSize2D aSize (xBitmap->getSize());
1802 return awt::Size(
1803 ::std::max(aSize.Width, sal_Int32(0.5 + aTextBBox.X2 - aTextBBox.X1)),
1804 aSize.Height+ nGap + nTextHeight);
1806 else
1807 return awt::Size(nTextWidth,nTextHeight);
1813 void Button::PaintIcon (
1814 const Reference<rendering::XCanvas>& rxCanvas,
1815 const sal_Int32 nTextHeight,
1816 const rendering::ViewState& rViewState)
1818 if (mpMode.get() == NULL)
1819 return;
1821 Reference<rendering::XBitmap> xBitmap (mpMode->mpIcon->GetBitmap(GetMode()));
1822 if (xBitmap.is())
1824 const sal_Int32 nX (maLocation.X
1825 + (maSize.Width-xBitmap->getSize().Width) / 2);
1826 const sal_Int32 nY (maLocation.Y
1827 + (maSize.Height - nTextHeight - xBitmap->getSize().Height) / 2);
1828 const rendering::RenderState aRenderState(
1829 geometry::AffineMatrix2D(1,0,nX, 0,1,nY),
1830 NULL,
1831 Sequence<double>(4),
1832 rendering::CompositeOperation::OVER);
1833 rxCanvas->drawBitmap(xBitmap, rViewState, aRenderState);
1840 PresenterBitmapDescriptor::Mode Button::GetMode (void) const
1842 if ( ! IsEnabled())
1843 return PresenterBitmapDescriptor::Disabled;
1844 else if (mbIsPressed)
1845 return PresenterBitmapDescriptor::ButtonDown;
1846 else if (mbIsOver)
1847 return PresenterBitmapDescriptor::MouseOver;
1848 else
1849 return PresenterBitmapDescriptor::Normal;
1855 //----- lang::XEventListener --------------------------------------------------
1857 void SAL_CALL Button::disposing (const css::lang::EventObject& rEvent)
1858 throw(css::uno::RuntimeException)
1860 (void)rEvent;
1861 mbIsListenerRegistered = false;
1862 Element::disposing(rEvent);
1865 } // end of anonymous namespace
1870 //===== PresenterToolBar::Label ===============================================
1872 namespace {
1874 Label::Label (const ::rtl::Reference<PresenterToolBar>& rpToolBar)
1875 : Element(rpToolBar)
1882 awt::Size Label::CreateBoundingSize (
1883 const Reference<rendering::XCanvas>& rxCanvas)
1885 if (mpMode.get() == NULL)
1886 return awt::Size(0,0);
1888 geometry::RealRectangle2D aTextBBox (mpMode->maText.GetBoundingBox(rxCanvas));
1889 return awt::Size(
1890 sal::static_int_cast<sal_Int32>(0.5 + aTextBBox.X2 - aTextBBox.X1),
1891 sal::static_int_cast<sal_Int32>(0.5 + aTextBBox.Y2 - aTextBBox.Y1));
1898 void Label::SetText (const OUString& rsText)
1900 OSL_ASSERT(mpToolBar.get() != NULL);
1901 if (mpMode.get() == NULL)
1902 return;
1904 const bool bRequestLayout (mpMode->maText.GetText().getLength() != rsText.getLength());
1906 mpMode->maText.SetText(rsText);
1907 // Just use the character count for determing whether a layout is
1908 // necessary. This is an optimization to avoid layouts every time a new
1909 // time value is set on some labels.
1910 if (bRequestLayout)
1911 mpToolBar->RequestLayout();
1912 else
1913 Invalidate(false);
1919 void Label::Paint (
1920 const Reference<rendering::XCanvas>& rxCanvas,
1921 const rendering::ViewState& rViewState)
1923 OSL_ASSERT(rxCanvas.is());
1924 if (mpMode.get() == NULL)
1925 return;
1927 mpMode->maText.Paint(rxCanvas, rViewState, GetBoundingBox(), awt::Point(0,0));
1933 bool Label::SetState (const bool bIsOver, const bool bIsPressed)
1935 // For labels there is no mouse over effect.
1936 (void)bIsOver;
1937 (void)bIsPressed;
1938 return Element::SetState(false, false);
1941 } // end of anonymous namespace
1946 //===== Text ==================================================================
1948 namespace {
1950 Text::Text (void)
1951 : msText(),
1952 mpFont()
1959 Text::Text (const Text& rText)
1960 : msText(rText.msText),
1961 mpFont(rText.mpFont)
1968 Text::Text (
1969 const OUString& rsText,
1970 const PresenterTheme::SharedFontDescriptor& rpFont)
1971 : msText(rsText),
1972 mpFont(rpFont)
1979 void Text::SetText (const OUString& rsText)
1981 msText = rsText;
1987 OUString Text::GetText (void) const
1989 return msText;
1995 PresenterTheme::SharedFontDescriptor Text::GetFont (void) const
1997 return mpFont;
2003 void Text::Paint (
2004 const Reference<rendering::XCanvas>& rxCanvas,
2005 const rendering::ViewState& rViewState,
2006 const awt::Rectangle& rBoundingBox,
2007 const awt::Point& rOffset)
2009 (void)rOffset;
2010 OSL_ASSERT(rxCanvas.is());
2012 if (msText.getLength() <= 0)
2013 return;
2014 if (mpFont.get() == NULL)
2015 return;
2017 if ( ! mpFont->mxFont.is())
2018 mpFont->PrepareFont(rxCanvas);
2019 if ( ! mpFont->mxFont.is())
2020 return;
2022 rendering::StringContext aContext (msText, 0, msText.getLength());
2024 Reference<rendering::XTextLayout> xLayout (
2025 mpFont->mxFont->createTextLayout(
2026 aContext,
2027 rendering::TextDirection::WEAK_LEFT_TO_RIGHT,
2028 0));
2030 geometry::RealRectangle2D aBox (xLayout->queryTextBounds());
2031 const double nTextWidth = aBox.X2 - aBox.X1;
2032 const double nY = rBoundingBox.Y + rBoundingBox.Height - aBox.Y2;
2033 const double nX = rBoundingBox.X + (rBoundingBox.Width - nTextWidth)/2;
2035 rendering::RenderState aRenderState(
2036 geometry::AffineMatrix2D(1,0,nX, 0,1,nY),
2037 NULL,
2038 Sequence<double>(4),
2039 rendering::CompositeOperation::SOURCE);
2040 PresenterCanvasHelper::SetDeviceColor(aRenderState, mpFont->mnColor);
2042 rxCanvas->drawText(
2043 aContext,
2044 mpFont->mxFont,
2045 rViewState,
2046 aRenderState,
2047 rendering::TextDirection::WEAK_LEFT_TO_RIGHT);
2053 geometry::RealRectangle2D Text::GetBoundingBox (const Reference<rendering::XCanvas>& rxCanvas)
2055 if (mpFont.get() != NULL && msText.getLength() > 0)
2057 if ( ! mpFont->mxFont.is())
2058 mpFont->PrepareFont(rxCanvas);
2059 if (mpFont->mxFont.is())
2061 rendering::StringContext aContext (msText, 0, msText.getLength());
2062 Reference<rendering::XTextLayout> xLayout (
2063 mpFont->mxFont->createTextLayout(
2064 aContext,
2065 rendering::TextDirection::WEAK_LEFT_TO_RIGHT,
2066 0));
2067 return xLayout->queryTextBounds();
2070 return geometry::RealRectangle2D(0,0,0,0);
2076 //===== ProgressLabel =========================================================
2078 ProgressLabel::ProgressLabel (const ::rtl::Reference<PresenterToolBar>& rpToolBar)
2079 : Label(rpToolBar)
2081 SetText(A2S("-/-"));
2087 void ProgressLabel::CurrentSlideHasChanged (void)
2089 Label::CurrentSlideHasChanged();
2090 OSL_ASSERT(mpToolBar.is());
2093 const sal_Int32 nCurrentSlideIndex (mpToolBar->GetCurrentSlideIndex() + 1);
2094 const sal_Int32 nSlideCount (mpToolBar->GetSlideCount());
2095 if (nCurrentSlideIndex >= 0 && nSlideCount > 0)
2096 SetText(
2097 OUString::valueOf(nCurrentSlideIndex)
2098 + OUString::createFromAscii(" / ")
2099 + OUString::valueOf(nSlideCount));
2100 else
2101 SetText(A2S(""));
2102 Invalidate();
2104 catch (RuntimeException&)
2112 //===== TimeFormatter =========================================================
2114 TimeFormatter::TimeFormatter (void)
2115 : mbIs24HourFormat(true),
2116 mbIsAmPmFormat(false),
2117 mbIsShowSeconds(true)
2124 OUString TimeFormatter::FormatTime (const oslDateTime& rTime)
2126 ::rtl::OUStringBuffer sText;
2128 const sal_Int32 nHours (sal::static_int_cast<sal_Int32>(rTime.Hours));
2129 const sal_Int32 nMinutes (sal::static_int_cast<sal_Int32>(rTime.Minutes));
2130 const sal_Int32 nSeconds(sal::static_int_cast<sal_Int32>(rTime.Seconds));
2132 // Hours
2133 if (mbIs24HourFormat)
2134 sText.append(OUString::valueOf(nHours));
2135 else
2136 sText.append(OUString::valueOf(
2137 sal::static_int_cast<sal_Int32>(nHours>12 ? nHours-12 : nHours)));
2139 sText.append(A2S(":"));
2141 // Minutes
2142 const OUString sMinutes (OUString::valueOf(nMinutes));
2143 if (sMinutes.getLength() == 1)
2144 sText.append(A2S("0"));
2145 sText.append(sMinutes);
2147 // Seconds
2148 if (mbIsShowSeconds)
2150 sText.append(A2S(":"));
2151 const OUString sSeconds (OUString::valueOf(nSeconds));
2152 if (sSeconds.getLength() == 1)
2153 sText.append(A2S("0"));
2154 sText.append(sSeconds);
2157 if (mbIsAmPmFormat)
2159 if (rTime.Hours < 12)
2160 sText.append(A2S("am"));
2161 else
2162 sText.append(A2S("pm"));
2164 return sText.makeStringAndClear();
2170 //===== TimeLabel =============================================================
2172 TimeLabel::TimeLabel (const ::rtl::Reference<PresenterToolBar>& rpToolBar)
2173 : Label(rpToolBar),
2174 mpListener()
2181 void SAL_CALL TimeLabel::disposing (void)
2183 PresenterClockTimer::Instance(mpToolBar->GetComponentContext())->RemoveListener(mpListener);
2184 mpListener.reset();
2190 void TimeLabel::ConnectToTimer (void)
2192 mpListener.reset(new Listener(this));
2193 PresenterClockTimer::Instance(mpToolBar->GetComponentContext())->AddListener(mpListener);
2199 //===== CurrentTimeLabel ======================================================
2201 ::rtl::Reference<Element> CurrentTimeLabel::Create (
2202 const ::rtl::Reference<PresenterToolBar>& rpToolBar)
2204 ::rtl::Reference<TimeLabel> pElement(new CurrentTimeLabel(rpToolBar));
2205 pElement->ConnectToTimer();
2206 return ::rtl::Reference<Element>(pElement.get());
2212 CurrentTimeLabel::~CurrentTimeLabel (void)
2219 CurrentTimeLabel::CurrentTimeLabel (
2220 const ::rtl::Reference<PresenterToolBar>& rpToolBar)
2221 : TimeLabel(rpToolBar),
2222 maTimeFormatter()
2229 void CurrentTimeLabel::TimeHasChanged (const oslDateTime& rCurrentTime)
2231 SetText(maTimeFormatter.FormatTime(rCurrentTime));
2232 Invalidate(false);
2238 void CurrentTimeLabel::SetModes (
2239 const SharedElementMode& rpNormalMode,
2240 const SharedElementMode& rpMouseOverMode,
2241 const SharedElementMode& rpSelectedMode,
2242 const SharedElementMode& rpDisabledMode)
2244 TimeLabel::SetModes(rpNormalMode, rpMouseOverMode, rpSelectedMode, rpDisabledMode);
2245 SetText(maTimeFormatter.FormatTime(PresenterClockTimer::GetCurrentTime()));
2251 //===== PresentationTimeLabel =================================================
2253 ::rtl::Reference<Element> PresentationTimeLabel::Create (
2254 const ::rtl::Reference<PresenterToolBar>& rpToolBar)
2256 ::rtl::Reference<TimeLabel> pElement(new PresentationTimeLabel(rpToolBar));
2257 pElement->ConnectToTimer();
2258 return ::rtl::Reference<Element>(pElement.get());
2264 PresentationTimeLabel::~PresentationTimeLabel (void)
2271 PresentationTimeLabel::PresentationTimeLabel (
2272 const ::rtl::Reference<PresenterToolBar>& rpToolBar)
2273 : TimeLabel(rpToolBar),
2274 maTimeFormatter(),
2275 maStartTimeValue()
2277 maStartTimeValue.Seconds = 0;
2278 maStartTimeValue.Nanosec = 0;
2284 void PresentationTimeLabel::TimeHasChanged (const oslDateTime& rCurrentTime)
2286 TimeValue aCurrentTimeValue;
2287 if (osl_getTimeValueFromDateTime(const_cast<oslDateTime*>(&rCurrentTime), &aCurrentTimeValue))
2289 if (maStartTimeValue.Seconds==0 && maStartTimeValue.Nanosec==0)
2291 // This method is called for the first time. Initialize the
2292 // start time. The start time is rounded to nearest second to
2293 // keep the time updates synchronized with the current time label.
2294 maStartTimeValue = aCurrentTimeValue;
2295 if (maStartTimeValue.Nanosec >= 500000000)
2296 maStartTimeValue.Seconds += 1;
2297 maStartTimeValue.Nanosec = 0;
2300 TimeValue aElapsedTimeValue;
2301 aElapsedTimeValue.Seconds = aCurrentTimeValue.Seconds - maStartTimeValue.Seconds;
2302 aElapsedTimeValue.Nanosec = aCurrentTimeValue.Nanosec - maStartTimeValue.Nanosec;
2304 oslDateTime aElapsedDateTime;
2305 if (osl_getDateTimeFromTimeValue(&aElapsedTimeValue, &aElapsedDateTime))
2307 SetText(maTimeFormatter.FormatTime(aElapsedDateTime));
2308 Invalidate(false);
2315 void PresentationTimeLabel::SetModes (
2316 const SharedElementMode& rpNormalMode,
2317 const SharedElementMode& rpMouseOverMode,
2318 const SharedElementMode& rpSelectedMode,
2319 const SharedElementMode& rpDisabledMode)
2321 TimeLabel::SetModes(rpNormalMode, rpMouseOverMode, rpSelectedMode, rpDisabledMode);
2323 oslDateTime aStartDateTime;
2324 if (osl_getDateTimeFromTimeValue(&maStartTimeValue, &aStartDateTime))
2326 SetText(maTimeFormatter.FormatTime(aStartDateTime));
2333 //===== VerticalSeparator =====================================================
2335 VerticalSeparator::VerticalSeparator (
2336 const ::rtl::Reference<PresenterToolBar>& rpToolBar)
2337 : Element(rpToolBar)
2344 void VerticalSeparator::Paint (
2345 const Reference<rendering::XCanvas>& rxCanvas,
2346 const rendering::ViewState& rViewState)
2348 OSL_ASSERT(rxCanvas.is());
2350 awt::Rectangle aBBox (GetBoundingBox());
2352 rendering::RenderState aRenderState(
2353 geometry::AffineMatrix2D(1,0,0, 0,1,0),
2354 NULL,
2355 Sequence<double>(4),
2356 rendering::CompositeOperation::OVER);
2357 if (mpMode.get() != NULL)
2359 PresenterTheme::SharedFontDescriptor pFont (mpMode->maText.GetFont());
2360 if (pFont.get() != NULL)
2361 PresenterCanvasHelper::SetDeviceColor(aRenderState, pFont->mnColor);
2364 if (aBBox.Height >= gnMinimalSeparatorSize + 2*gnSeparatorInset)
2366 aBBox.Height -= 2*gnSeparatorInset;
2367 aBBox.Y += gnSeparatorInset;
2369 rxCanvas->fillPolyPolygon(
2370 PresenterGeometryHelper::CreatePolygon(aBBox, rxCanvas->getDevice()),
2371 rViewState,
2372 aRenderState);
2378 awt::Size VerticalSeparator::CreateBoundingSize (
2379 const Reference<rendering::XCanvas>& rxCanvas)
2381 (void)rxCanvas;
2382 return awt::Size(1,20);
2388 bool VerticalSeparator::IsFilling (void) const
2390 return true;
2396 //===== HorizontalSeparator ===================================================
2398 HorizontalSeparator::HorizontalSeparator (
2399 const ::rtl::Reference<PresenterToolBar>& rpToolBar)
2400 : Element(rpToolBar)
2407 void HorizontalSeparator::Paint (
2408 const Reference<rendering::XCanvas>& rxCanvas,
2409 const rendering::ViewState& rViewState)
2411 OSL_ASSERT(rxCanvas.is());
2413 awt::Rectangle aBBox (GetBoundingBox());
2415 rendering::RenderState aRenderState(
2416 geometry::AffineMatrix2D(1,0,0, 0,1,0),
2417 NULL,
2418 Sequence<double>(4),
2419 rendering::CompositeOperation::OVER);
2420 if (mpMode.get() != NULL)
2422 PresenterTheme::SharedFontDescriptor pFont (mpMode->maText.GetFont());
2423 if (pFont.get() != NULL)
2424 PresenterCanvasHelper::SetDeviceColor(aRenderState, pFont->mnColor);
2427 if (aBBox.Width >= gnMinimalSeparatorSize+2*gnSeparatorInset)
2429 aBBox.Width -= 2*gnSeparatorInset;
2430 aBBox.X += gnSeparatorInset;
2432 rxCanvas->fillPolyPolygon(
2433 PresenterGeometryHelper::CreatePolygon(aBBox, rxCanvas->getDevice()),
2434 rViewState,
2435 aRenderState);
2441 awt::Size HorizontalSeparator::CreateBoundingSize (
2442 const Reference<rendering::XCanvas>& rxCanvas)
2444 (void)rxCanvas;
2445 return awt::Size(20,1);
2451 bool HorizontalSeparator::IsFilling (void) const
2453 return true;
2459 } // end of anonymous namespace
2462 } } // end of namespace ::sdext::presenter