1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
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 #include <vcl/svapp.hxx>
21 #include <vcl/settings.hxx>
22 #include "PresenterToolBar.hxx"
24 #include "PresenterBitmapContainer.hxx"
25 #include "PresenterCanvasHelper.hxx"
26 #include "PresenterGeometryHelper.hxx"
27 #include "PresenterPaintManager.hxx"
28 #include "PresenterPaneBase.hxx"
29 #include "PresenterPaneFactory.hxx"
30 #include "PresenterTimer.hxx"
31 #include "PresenterWindowManager.hxx"
33 #include <cppuhelper/compbase.hxx>
34 #include <com/sun/star/awt/FontDescriptor.hpp>
35 #include <com/sun/star/awt/PosSize.hpp>
36 #include <com/sun/star/awt/XWindowPeer.hpp>
37 #include <com/sun/star/deployment/XPackageInformationProvider.hpp>
38 #include <com/sun/star/drawing/framework/XControllerManager.hpp>
39 #include <com/sun/star/drawing/framework/XConfigurationController.hpp>
40 #include <com/sun/star/drawing/framework/XPane.hpp>
41 #include <com/sun/star/geometry/AffineMatrix2D.hpp>
42 #include <com/sun/star/lang/XServiceName.hpp>
43 #include <com/sun/star/rendering/CompositeOperation.hpp>
44 #include <com/sun/star/rendering/RenderState.hpp>
45 #include <com/sun/star/rendering/TextDirection.hpp>
46 #include <com/sun/star/rendering/ViewState.hpp>
47 #include <com/sun/star/rendering/XSpriteCanvas.hpp>
48 #include <com/sun/star/text/XTextRange.hpp>
49 #include <com/sun/star/util/Color.hpp>
50 #include <com/sun/star/util/XURLTransformer.hpp>
51 #include <rtl/ustrbuf.hxx>
53 using namespace ::com::sun::star
;
54 using namespace ::com::sun::star::uno
;
55 using namespace ::com::sun::star::drawing::framework
;
57 namespace sdext
{ namespace presenter
{
59 static const sal_Int32
gnGapSize (20);
68 const OUString
& rsText
,
69 const PresenterTheme::SharedFontDescriptor
& rpFont
);
71 void SetText (const OUString
& rsText
);
72 const OUString
& GetText() const;
73 const PresenterTheme::SharedFontDescriptor
& GetFont() const;
76 const Reference
<rendering::XCanvas
>& rxCanvas
,
77 const rendering::ViewState
& rViewState
,
78 const awt::Rectangle
& rBoundingBox
);
80 geometry::RealRectangle2D
GetBoundingBox (
81 const Reference
<rendering::XCanvas
>& rxCanvas
);
85 PresenterTheme::SharedFontDescriptor mpFont
;
92 ElementMode(const ElementMode
&) = delete;
93 ElementMode
& operator=(const ElementMode
&) = delete;
95 SharedBitmapDescriptor mpIcon
;
99 void ReadElementMode (
100 const Reference
<beans::XPropertySet
>& rxProperties
,
101 const OUString
& rsModeName
,
102 std::shared_ptr
<ElementMode
> const & rpDefaultMode
,
103 ::sdext::presenter::PresenterToolBar::Context
const & rContext
);
105 typedef std::shared_ptr
<ElementMode
> SharedElementMode
;
107 } // end of anonymous namespace
109 class PresenterToolBar::Context
113 Context(const Context
&) = delete;
114 Context
& operator=(const Context
&) = delete;
115 Reference
<drawing::XPresenterHelper
> mxPresenterHelper
;
116 css::uno::Reference
<css::rendering::XCanvas
> mxCanvas
;
119 //===== PresenterToolBar::Element =============================================
122 typedef cppu::WeakComponentImplHelper
<
123 css::document::XEventListener
,
124 css::frame::XStatusListener
125 > ElementInterfaceBase
;
128 : private ::cppu::BaseMutex
,
129 public ElementInterfaceBase
132 explicit Element (const ::rtl::Reference
<PresenterToolBar
>& rpToolBar
);
133 Element(const Element
&) = delete;
134 Element
& operator=(const Element
&) = delete;
136 virtual void SAL_CALL
disposing() override
;
138 virtual void SetModes (
139 const SharedElementMode
& rpNormalMode
,
140 const SharedElementMode
& rpMouseOverMode
,
141 const SharedElementMode
& rpSelectedMode
,
142 const SharedElementMode
& rpDisabledMode
);
143 void CurrentSlideHasChanged();
144 void SetLocation (const awt::Point
& rLocation
);
145 void SetSize (const geometry::RealSize2D
& rSize
);
147 const Reference
<rendering::XCanvas
>& rxCanvas
,
148 const rendering::ViewState
& rViewState
) = 0;
149 awt::Size
const & GetBoundingSize (
150 const Reference
<rendering::XCanvas
>& rxCanvas
);
151 awt::Rectangle
GetBoundingBox() const;
152 virtual bool SetState (const bool bIsOver
, const bool bIsPressed
);
153 void Invalidate (const bool bSynchronous
);
154 bool IsOutside (const awt::Rectangle
& rBox
);
155 virtual bool IsFilling() const;
158 // lang::XEventListener
160 virtual void SAL_CALL
disposing (const css::lang::EventObject
& rEvent
) override
;
162 // document::XEventListener
164 virtual void SAL_CALL
notifyEvent (const css::document::EventObject
& rEvent
) override
;
166 // frame::XStatusListener
168 virtual void SAL_CALL
statusChanged (const css::frame::FeatureStateEvent
& rEvent
) override
;
171 ::rtl::Reference
<PresenterToolBar
> mpToolBar
;
172 awt::Point maLocation
;
174 SharedElementMode mpNormal
;
175 SharedElementMode mpMouseOver
;
176 SharedElementMode mpSelected
;
177 SharedElementMode mpDisabled
;
178 SharedElementMode mpMode
;
183 virtual awt::Size
CreateBoundingSize (
184 const Reference
<rendering::XCanvas
>& rxCanvas
) = 0;
186 bool IsEnabled() const { return mbIsEnabled
;}
191 } // end of anonymous namespace
193 class PresenterToolBar::ElementContainerPart
194 : public ::std::vector
<rtl::Reference
<Element
> >
198 //===== Button ================================================================
202 class Button
: public Element
205 static ::rtl::Reference
<Element
> Create (
206 const ::rtl::Reference
<PresenterToolBar
>& rpToolBar
);
208 virtual void SAL_CALL
disposing() override
;
211 const Reference
<rendering::XCanvas
>& rxCanvas
,
212 const rendering::ViewState
& rViewState
) override
;
214 // lang::XEventListener
216 virtual void SAL_CALL
disposing (const css::lang::EventObject
& rEvent
) override
;
219 virtual awt::Size
CreateBoundingSize (
220 const Reference
<rendering::XCanvas
>& rxCanvas
) override
;
223 bool mbIsListenerRegistered
;
225 Button (const ::rtl::Reference
<PresenterToolBar
>& rpToolBar
);
228 const Reference
<rendering::XCanvas
>& rxCanvas
,
229 const sal_Int32 nTextHeight
,
230 const rendering::ViewState
& rViewState
);
231 PresenterBitmapDescriptor::Mode
GetMode() const;
234 //===== Label =================================================================
236 class Label
: public Element
239 explicit Label (const ::rtl::Reference
<PresenterToolBar
>& rpToolBar
);
241 void SetText (const OUString
& rsText
);
243 const Reference
<rendering::XCanvas
>& rxCanvas
,
244 const rendering::ViewState
& rViewState
) override
;
245 virtual bool SetState (const bool bIsOver
, const bool bIsPressed
) override
;
248 virtual awt::Size
CreateBoundingSize (
249 const Reference
<rendering::XCanvas
>& rxCanvas
) override
;
252 // Some specialized controls.
257 static OUString
FormatTime (const oslDateTime
& rTime
);
260 class TimeLabel
: public Label
263 void ConnectToTimer();
264 virtual void TimeHasChanged (const oslDateTime
& rCurrentTime
) = 0;
266 explicit TimeLabel(const ::rtl::Reference
<PresenterToolBar
>& rpToolBar
);
267 using Element::disposing
;
268 virtual void SAL_CALL
disposing() override
;
270 class Listener
: public PresenterClockTimer::Listener
273 explicit Listener (const ::rtl::Reference
<TimeLabel
>& rxLabel
)
274 : mxLabel(rxLabel
) {}
275 virtual ~Listener() {}
276 virtual void TimeHasChanged (const oslDateTime
& rCurrentTime
) override
277 { if (mxLabel
.is()) mxLabel
->TimeHasChanged(rCurrentTime
); }
279 ::rtl::Reference
<TimeLabel
> mxLabel
;
281 std::shared_ptr
<PresenterClockTimer::Listener
> mpListener
;
284 class CurrentTimeLabel
: public TimeLabel
287 static ::rtl::Reference
<Element
> Create (
288 const ::rtl::Reference
<PresenterToolBar
>& rpToolBar
);
289 virtual void SetModes (
290 const SharedElementMode
& rpNormalMode
,
291 const SharedElementMode
& rpMouseOverMode
,
292 const SharedElementMode
& rpSelectedMode
,
293 const SharedElementMode
& rpDisabledMode
) override
;
295 CurrentTimeLabel (const ::rtl::Reference
<PresenterToolBar
>& rpToolBar
);
296 virtual ~CurrentTimeLabel() override
;
297 virtual void TimeHasChanged (const oslDateTime
& rCurrentTime
) override
;
300 class PresentationTimeLabel
: public TimeLabel
, public IPresentationTime
303 static ::rtl::Reference
<Element
> Create (
304 const ::rtl::Reference
<PresenterToolBar
>& rpToolBar
);
305 virtual void SetModes (
306 const SharedElementMode
& rpNormalMode
,
307 const SharedElementMode
& rpMouseOverMode
,
308 const SharedElementMode
& rpSelectedMode
,
309 const SharedElementMode
& rpDisabledMode
) override
;
310 virtual void restart() override
;
312 TimeValue maStartTimeValue
;
313 PresentationTimeLabel (const ::rtl::Reference
<PresenterToolBar
>& rpToolBar
);
314 virtual ~PresentationTimeLabel() override
;
315 virtual void TimeHasChanged (const oslDateTime
& rCurrentTime
) override
;
318 class VerticalSeparator
: public Element
321 explicit VerticalSeparator (const ::rtl::Reference
<PresenterToolBar
>& rpToolBar
);
323 const Reference
<rendering::XCanvas
>& rxCanvas
,
324 const rendering::ViewState
& rViewState
) override
;
325 virtual bool IsFilling() const override
;
328 virtual awt::Size
CreateBoundingSize (
329 const Reference
<rendering::XCanvas
>& rxCanvas
) override
;
332 class HorizontalSeparator
: public Element
335 explicit HorizontalSeparator (const ::rtl::Reference
<PresenterToolBar
>& rpToolBar
);
337 const Reference
<rendering::XCanvas
>& rxCanvas
,
338 const rendering::ViewState
& rViewState
) override
;
339 virtual bool IsFilling() const override
;
342 virtual awt::Size
CreateBoundingSize (
343 const Reference
<rendering::XCanvas
>& rxCanvas
) override
;
345 } // end of anonymous namespace
347 //===== PresenterToolBar ======================================================
349 PresenterToolBar::PresenterToolBar (
350 const Reference
<XComponentContext
>& rxContext
,
351 const css::uno::Reference
<css::awt::XWindow
>& rxWindow
,
352 const css::uno::Reference
<css::rendering::XCanvas
>& rxCanvas
,
353 const ::rtl::Reference
<PresenterController
>& rpPresenterController
,
354 const Anchor eAnchor
)
355 : PresenterToolBarInterfaceBase(m_aMutex
),
356 mxComponentContext(rxContext
),
357 maElementContainer(),
358 mpCurrentContainerPart(),
361 mxSlideShowController(),
363 mpPresenterController(rpPresenterController
),
364 mbIsLayoutPending(false),
370 void PresenterToolBar::Initialize (
371 const OUString
& rsConfigurationPath
)
375 CreateControls(rsConfigurationPath
);
379 mxWindow
->addWindowListener(this);
380 mxWindow
->addPaintListener(this);
381 mxWindow
->addMouseListener(this);
382 mxWindow
->addMouseMotionListener(this);
384 Reference
<awt::XWindowPeer
> xPeer (mxWindow
, UNO_QUERY
);
386 xPeer
->setBackground(util::Color(0xff000000));
388 mxWindow
->setVisible(true);
391 mxSlideShowController
= mpPresenterController
->GetSlideShowController();
393 mbIsLayoutPending
= true;
395 catch (RuntimeException
&)
397 mpCurrentContainerPart
.reset();
398 maElementContainer
.clear();
403 PresenterToolBar::~PresenterToolBar()
407 void SAL_CALL
PresenterToolBar::disposing()
411 mxWindow
->removeWindowListener(this);
412 mxWindow
->removePaintListener(this);
413 mxWindow
->removeMouseListener(this);
414 mxWindow
->removeMouseMotionListener(this);
418 // Dispose tool bar elements.
419 for (const auto& rxPart
: maElementContainer
)
421 OSL_ASSERT(rxPart
!= nullptr);
422 for (rtl::Reference
<Element
>& pElement
: *rxPart
)
424 if (pElement
.get() != nullptr)
426 Reference
<lang::XComponent
> xComponent (
427 static_cast<XWeak
*>(pElement
.get()), UNO_QUERY
);
429 xComponent
->dispose();
434 mpCurrentContainerPart
.reset();
435 maElementContainer
.clear();
438 void PresenterToolBar::InvalidateArea (
439 const awt::Rectangle
& rRepaintBox
,
440 const bool bSynchronous
)
442 std::shared_ptr
<PresenterPaintManager
> xManager(mpPresenterController
->GetPaintManager());
445 xManager
->Invalidate(
451 void PresenterToolBar::RequestLayout()
453 mbIsLayoutPending
= true;
455 std::shared_ptr
<PresenterPaintManager
> xManager(mpPresenterController
->GetPaintManager());
459 xManager
->Invalidate(mxWindow
);
462 geometry::RealSize2D
const & PresenterToolBar::GetMinimalSize()
464 if (mbIsLayoutPending
)
466 return maMinimalSize
;
469 const ::rtl::Reference
<PresenterController
>& PresenterToolBar::GetPresenterController() const
471 return mpPresenterController
;
474 const Reference
<XComponentContext
>& PresenterToolBar::GetComponentContext() const
476 return mxComponentContext
;
479 //----- lang::XEventListener -------------------------------------------------
481 void SAL_CALL
PresenterToolBar::disposing (const lang::EventObject
& rEventObject
)
483 if (rEventObject
.Source
== mxWindow
)
487 //----- XWindowListener -------------------------------------------------------
489 void SAL_CALL
PresenterToolBar::windowResized (const awt::WindowEvent
&)
491 mbIsLayoutPending
= true;
494 void SAL_CALL
PresenterToolBar::windowMoved (const awt::WindowEvent
&) {}
496 void SAL_CALL
PresenterToolBar::windowShown (const lang::EventObject
&)
498 mbIsLayoutPending
= true;
501 void SAL_CALL
PresenterToolBar::windowHidden (const lang::EventObject
&) {}
503 //----- XPaintListener --------------------------------------------------------
504 void SAL_CALL
PresenterToolBar::windowPaint (const css::awt::PaintEvent
& rEvent
)
506 if ( ! mxCanvas
.is())
509 if ( ! mbIsPresenterViewActive
)
512 const rendering::ViewState
aViewState (
513 geometry::AffineMatrix2D(1,0,0, 0,1,0),
514 PresenterGeometryHelper::CreatePolygon(rEvent
.UpdateRect
, mxCanvas
->getDevice()));
516 if (mbIsLayoutPending
)
519 Paint(rEvent
.UpdateRect
, aViewState
);
521 // Make the back buffer visible.
522 Reference
<rendering::XSpriteCanvas
> xSpriteCanvas (mxCanvas
, UNO_QUERY
);
523 if (xSpriteCanvas
.is())
524 xSpriteCanvas
->updateScreen(false);
527 //----- XMouseListener --------------------------------------------------------
528 void SAL_CALL
PresenterToolBar::mousePressed (const css::awt::MouseEvent
& rEvent
)
531 CheckMouseOver(rEvent
, true, true);
534 void SAL_CALL
PresenterToolBar::mouseReleased (const css::awt::MouseEvent
& rEvent
)
537 CheckMouseOver(rEvent
, true);
540 void SAL_CALL
PresenterToolBar::mouseEntered (const css::awt::MouseEvent
& rEvent
)
543 CheckMouseOver(rEvent
, true);
546 void SAL_CALL
PresenterToolBar::mouseExited (const css::awt::MouseEvent
& rEvent
)
549 CheckMouseOver(rEvent
, false);
552 //----- XMouseMotionListener --------------------------------------------------
554 void SAL_CALL
PresenterToolBar::mouseMoved (const css::awt::MouseEvent
& rEvent
)
557 CheckMouseOver(rEvent
, true);
560 void SAL_CALL
PresenterToolBar::mouseDragged (const css::awt::MouseEvent
&)
565 //----- XDrawView -------------------------------------------------------------
567 void SAL_CALL
PresenterToolBar::setCurrentPage (const Reference
<drawing::XDrawPage
>& rxSlide
)
569 if (rxSlide
!= mxCurrentSlide
)
571 mxCurrentSlide
= rxSlide
;
576 Reference
<drawing::XDrawPage
> SAL_CALL
PresenterToolBar::getCurrentPage()
578 return mxCurrentSlide
;
582 void PresenterToolBar::CreateControls (
583 const OUString
& rsConfigurationPath
)
585 if ( ! mxWindow
.is())
588 // Expand the macro in the bitmap file names.
589 PresenterConfigurationAccess
aConfiguration (
591 "/org.openoffice.Office.PresenterScreen/",
592 PresenterConfigurationAccess::READ_ONLY
);
594 mpCurrentContainerPart
.reset(new ElementContainerPart
);
595 maElementContainer
.clear();
596 maElementContainer
.push_back(mpCurrentContainerPart
);
598 Reference
<container::XHierarchicalNameAccess
> xToolBarNode (
599 aConfiguration
.GetConfigurationNode(rsConfigurationPath
),
601 if (!xToolBarNode
.is())
604 Reference
<container::XNameAccess
> xEntries (
605 PresenterConfigurationAccess::GetConfigurationNode(xToolBarNode
, "Entries"),
608 aContext
.mxPresenterHelper
= mpPresenterController
->GetPresenterHelper();
609 aContext
.mxCanvas
= mxCanvas
;
611 && aContext
.mxPresenterHelper
.is()
612 && aContext
.mxCanvas
.is())
614 PresenterConfigurationAccess::ForAll(
616 [this, &aContext
] (OUString
const&, uno::Reference
<beans::XPropertySet
> const& xProps
)
618 return this->ProcessEntry(xProps
, aContext
);
623 void PresenterToolBar::ProcessEntry (
624 const Reference
<beans::XPropertySet
>& rxProperties
,
625 Context
const & rContext
)
627 if ( ! rxProperties
.is())
630 // Type has to be present.
632 if ( ! (PresenterConfigurationAccess::GetProperty(rxProperties
, "Type") >>= sType
))
635 // Read mode specific values.
636 SharedElementMode
pNormalMode (new ElementMode());
637 SharedElementMode
pMouseOverMode (new ElementMode());
638 SharedElementMode
pSelectedMode (new ElementMode());
639 SharedElementMode
pDisabledMode (new ElementMode());
640 pNormalMode
->ReadElementMode(rxProperties
, "Normal", pNormalMode
, rContext
);
641 pMouseOverMode
->ReadElementMode(rxProperties
, "MouseOver", pNormalMode
, rContext
);
642 pSelectedMode
->ReadElementMode(rxProperties
, "Selected", pNormalMode
, rContext
);
643 pDisabledMode
->ReadElementMode(rxProperties
, "Disabled", pNormalMode
, rContext
);
645 // Create new element.
646 ::rtl::Reference
<Element
> pElement
;
647 if ( sType
== "Button" )
648 pElement
= Button::Create(this);
649 else if ( sType
== "CurrentTimeLabel" )
650 pElement
= CurrentTimeLabel::Create(this);
651 else if ( sType
== "PresentationTimeLabel" )
652 pElement
= PresentationTimeLabel::Create(this);
653 else if ( sType
== "VerticalSeparator" )
654 pElement
.set(new VerticalSeparator(this));
655 else if ( sType
== "HorizontalSeparator" )
656 pElement
.set(new HorizontalSeparator(this));
657 else if ( sType
== "Label" )
658 pElement
.set(new Label(this));
659 else if ( sType
== "ChangeOrientation" )
661 mpCurrentContainerPart
.reset(new ElementContainerPart
);
662 maElementContainer
.push_back(mpCurrentContainerPart
);
667 pElement
->SetModes( pNormalMode
, pMouseOverMode
, pSelectedMode
, pDisabledMode
);
668 pElement
->UpdateState();
669 if (mpCurrentContainerPart
.get() != nullptr)
670 mpCurrentContainerPart
->push_back(pElement
);
674 void PresenterToolBar::Layout (
675 const Reference
<rendering::XCanvas
>& rxCanvas
)
677 if (maElementContainer
.empty())
680 mbIsLayoutPending
= false;
682 const awt::Rectangle
aWindowBox (mxWindow
->getPosSize());
683 ::std::vector
<geometry::RealSize2D
> aPartSizes (maElementContainer
.size());
684 geometry::RealSize2D
aTotalSize (0,0);
685 bool bIsHorizontal (true);
686 sal_Int32
nIndex (0);
687 double nTotalHorizontalGap (0);
688 sal_Int32
nGapCount (0);
689 for (const auto& rxPart
: maElementContainer
)
691 geometry::RealSize2D
aSize (CalculatePartSize(rxCanvas
, rxPart
, bIsHorizontal
));
693 // Remember the size of each part for later.
694 aPartSizes
[nIndex
] = aSize
;
696 // Add gaps between elements.
697 if (rxPart
->size()>1 && bIsHorizontal
)
699 nTotalHorizontalGap
+= (rxPart
->size() - 1) * gnGapSize
;
700 nGapCount
+= rxPart
->size() - 1;
703 // Orientation changes for each part.
704 bIsHorizontal
= !bIsHorizontal
;
705 // Width is accumulated.
706 aTotalSize
.Width
+= aSize
.Width
;
707 // Height is the maximum height of all parts.
708 aTotalSize
.Height
= ::std::max(aTotalSize
.Height
, aSize
.Height
);
711 // Add gaps between parts.
712 if (maElementContainer
.size() > 1)
714 nTotalHorizontalGap
+= (maElementContainer
.size() - 1) * gnGapSize
;
715 nGapCount
+= maElementContainer
.size()-1;
718 // Calculate the minimal size so that the window size of the tool bar
719 // can be adapted accordingly.
720 maMinimalSize
= aTotalSize
;
721 maMinimalSize
.Width
+= nTotalHorizontalGap
;
723 // Calculate the gaps between elements.
724 double nGapWidth (0);
727 if (aTotalSize
.Width
+ nTotalHorizontalGap
> aWindowBox
.Width
)
728 nTotalHorizontalGap
= aWindowBox
.Width
- aTotalSize
.Width
;
729 nGapWidth
= nTotalHorizontalGap
/ nGapCount
;
732 // Determine the location of the left edge.
736 case Left
: nX
= 0; break;
737 case Center
: nX
= (aWindowBox
.Width
- aTotalSize
.Width
- nTotalHorizontalGap
) / 2; break;
741 double nY ((aWindowBox
.Height
- aTotalSize
.Height
) / 2);
742 bIsHorizontal
= true;
744 /* push front or back ? ... */
745 /// check whether RTL interface or not
746 if(!AllSettings::GetLayoutRTL()){
748 for (const auto& rxPart
: maElementContainer
)
750 geometry::RealRectangle2D
aBoundingBox(
752 nX
+aPartSizes
[nIndex
].Width
, nY
+aTotalSize
.Height
);
754 // Add space for gaps between elements.
755 if (rxPart
->size() > 1)
757 aBoundingBox
.X2
+= (rxPart
->size() - 1) * nGapWidth
;
759 LayoutPart(rxCanvas
, rxPart
, aBoundingBox
, aPartSizes
[nIndex
], bIsHorizontal
);
760 bIsHorizontal
= !bIsHorizontal
;
761 nX
+= aBoundingBox
.X2
- aBoundingBox
.X1
+ nGapWidth
;
766 ElementContainer::iterator iPart
;
767 ElementContainer::iterator
iBegin (maElementContainer
.begin());
768 for (iPart
=maElementContainer
.end()-1, nIndex
=2; iPart
!=iBegin
-1; --iPart
, --nIndex
)
770 geometry::RealRectangle2D
aBoundingBox(
772 nX
+aPartSizes
[nIndex
].Width
, nY
+aTotalSize
.Height
);
774 // Add space for gaps between elements.
775 if ((*iPart
)->size() > 1)
777 aBoundingBox
.X2
+= ((*iPart
)->size()-1) * nGapWidth
;
779 LayoutPart(rxCanvas
, *iPart
, aBoundingBox
, aPartSizes
[nIndex
], bIsHorizontal
);
780 bIsHorizontal
= !bIsHorizontal
;
781 nX
+= aBoundingBox
.X2
- aBoundingBox
.X1
+ nGapWidth
;
785 // The whole window has to be repainted.
786 std::shared_ptr
<PresenterPaintManager
> xManager(mpPresenterController
->GetPaintManager());
789 xManager
->Invalidate(mxWindow
);
792 geometry::RealSize2D
PresenterToolBar::CalculatePartSize (
793 const Reference
<rendering::XCanvas
>& rxCanvas
,
794 const SharedElementContainerPart
& rpPart
,
795 const bool bIsHorizontal
)
797 geometry::RealSize2D
aTotalSize (0,0);
801 // Calculate the summed width of all elements.
802 for (const auto& rxElement
: *rpPart
)
804 if (rxElement
.get() == nullptr)
807 const awt::Size
aBSize (rxElement
->GetBoundingSize(rxCanvas
));
810 aTotalSize
.Width
+= aBSize
.Width
;
811 if (aBSize
.Height
> aTotalSize
.Height
)
812 aTotalSize
.Height
= aBSize
.Height
;
816 aTotalSize
.Height
+= aBSize
.Height
;
817 if (aBSize
.Width
> aTotalSize
.Width
)
818 aTotalSize
.Width
= aBSize
.Width
;
825 void PresenterToolBar::LayoutPart (
826 const Reference
<rendering::XCanvas
>& rxCanvas
,
827 const SharedElementContainerPart
& rpPart
,
828 const geometry::RealRectangle2D
& rBoundingBox
,
829 const geometry::RealSize2D
& rPartSize
,
830 const bool bIsHorizontal
)
833 if (rpPart
->size() > 1)
836 nGap
= (rBoundingBox
.X2
- rBoundingBox
.X1
- rPartSize
.Width
) / (rpPart
->size()-1);
838 nGap
= (rBoundingBox
.Y2
- rBoundingBox
.Y1
- rPartSize
.Height
) / (rpPart
->size()-1);
841 // Place the elements.
842 double nX (rBoundingBox
.X1
);
843 double nY (rBoundingBox
.Y1
);
845 /// check whether RTL interface or not
846 if(!AllSettings::GetLayoutRTL()){
847 for (auto& rxElement
: *rpPart
)
849 if (rxElement
.get() == nullptr)
852 const awt::Size
aElementSize (rxElement
->GetBoundingSize(rxCanvas
));
855 if (rxElement
->IsFilling())
857 nY
= rBoundingBox
.Y1
;
858 rxElement
->SetSize(geometry::RealSize2D(aElementSize
.Width
, rBoundingBox
.Y2
- rBoundingBox
.Y1
));
861 nY
= rBoundingBox
.Y1
+ (rBoundingBox
.Y2
-rBoundingBox
.Y1
- aElementSize
.Height
) / 2;
862 rxElement
->SetLocation(awt::Point(sal_Int32(0.5 + nX
), sal_Int32(0.5 + nY
)));
863 nX
+= aElementSize
.Width
+ nGap
;
867 if (rxElement
->IsFilling())
869 nX
= rBoundingBox
.X1
;
870 rxElement
->SetSize(geometry::RealSize2D(rBoundingBox
.X2
- rBoundingBox
.X1
, aElementSize
.Height
));
873 nX
= rBoundingBox
.X1
+ (rBoundingBox
.X2
-rBoundingBox
.X1
- aElementSize
.Width
) / 2;
874 rxElement
->SetLocation(awt::Point(sal_Int32(0.5 + nX
), sal_Int32(0.5 + nY
)));
875 nY
+= aElementSize
.Height
+ nGap
;
880 ElementContainerPart::const_iterator iElement
;
881 ElementContainerPart::const_iterator
iEnd (rpPart
->end());
882 ElementContainerPart::const_iterator
iBegin (rpPart
->begin());
884 for (iElement
=rpPart
->end()-1; iElement
!=iBegin
-1; --iElement
)
886 if (iElement
->get() == nullptr)
889 const awt::Size
aElementSize ((*iElement
)->GetBoundingSize(rxCanvas
));
892 if ((*iElement
)->IsFilling())
894 nY
= rBoundingBox
.Y1
;
895 (*iElement
)->SetSize(geometry::RealSize2D(aElementSize
.Width
, rBoundingBox
.Y2
- rBoundingBox
.Y1
));
898 nY
= rBoundingBox
.Y1
+ (rBoundingBox
.Y2
-rBoundingBox
.Y1
- aElementSize
.Height
) / 2;
899 (*iElement
)->SetLocation(awt::Point(sal_Int32(0.5 + nX
), sal_Int32(0.5 + nY
)));
900 nX
+= aElementSize
.Width
+ nGap
;
904 // reverse presentation time with current time
905 if (iElement
==iBegin
){
908 else if (iElement
==iBegin
+2){
911 const awt::Size
aNewElementSize ((*iElement
)->GetBoundingSize(rxCanvas
));
912 if ((*iElement
)->IsFilling())
914 nX
= rBoundingBox
.X1
;
915 (*iElement
)->SetSize(geometry::RealSize2D(rBoundingBox
.X2
- rBoundingBox
.X1
, aNewElementSize
.Height
));
918 nX
= rBoundingBox
.X1
+ (rBoundingBox
.X2
-rBoundingBox
.X1
- aNewElementSize
.Width
) / 2;
919 (*iElement
)->SetLocation(awt::Point(sal_Int32(0.5 + nX
), sal_Int32(0.5 + nY
)));
920 nY
+= aNewElementSize
.Height
+ nGap
;
922 // return the index as it was before the reversing
923 if (iElement
==iBegin
)
925 else if (iElement
==iBegin
+2)
932 void PresenterToolBar::Paint (
933 const awt::Rectangle
& rUpdateBox
,
934 const rendering::ViewState
& rViewState
)
936 OSL_ASSERT(mxCanvas
.is());
938 for (const auto& rxPart
: maElementContainer
)
940 for (auto& rxElement
: *rxPart
)
942 if (rxElement
.get() != nullptr)
944 if ( ! rxElement
->IsOutside(rUpdateBox
))
945 rxElement
->Paint(mxCanvas
, rViewState
);
951 void PresenterToolBar::UpdateSlideNumber()
953 if( mxSlideShowController
.is() )
955 for (const auto& rxPart
: maElementContainer
)
957 for (auto& rxElement
: *rxPart
)
959 if (rxElement
.get() != nullptr)
960 rxElement
->CurrentSlideHasChanged();
966 void PresenterToolBar::CheckMouseOver (
967 const css::awt::MouseEvent
& rEvent
,
968 const bool bOverWindow
,
969 const bool bMouseDown
)
971 css::awt::MouseEvent rTemp
=rEvent
;
972 if(AllSettings::GetLayoutRTL()){
973 awt::Rectangle aWindowBox
= mxWindow
->getPosSize();
974 rTemp
.X
=aWindowBox
.Width
-rTemp
.X
;
976 for (const auto& rxPart
: maElementContainer
)
978 for (auto& rxElement
: *rxPart
)
980 if (rxElement
.get() == nullptr)
983 awt::Rectangle
aBox (rxElement
->GetBoundingBox());
984 const bool bIsOver
= bOverWindow
986 && aBox
.Width
+aBox
.X
-1 >= rTemp
.X
988 && aBox
.Height
+aBox
.Y
-1 >= rTemp
.Y
;
991 bIsOver
&& rTemp
.Buttons
!=0 && bMouseDown
&& rTemp
.ClickCount
>0);
996 void PresenterToolBar::ThrowIfDisposed() const
998 if (rBHelper
.bDisposed
|| rBHelper
.bInDispose
)
1000 throw lang::DisposedException (
1001 "PresenterToolBar has already been disposed",
1002 const_cast<uno::XWeak
*>(static_cast<const uno::XWeak
*>(this)));
1006 //===== PresenterToolBarView ==================================================
1008 PresenterToolBarView::PresenterToolBarView (
1009 const Reference
<XComponentContext
>& rxContext
,
1010 const Reference
<XResourceId
>& rxViewId
,
1011 const Reference
<frame::XController
>& rxController
,
1012 const ::rtl::Reference
<PresenterController
>& rpPresenterController
)
1013 : PresenterToolBarViewInterfaceBase(m_aMutex
),
1018 mpPresenterController(rpPresenterController
),
1023 Reference
<XControllerManager
> xCM (rxController
, UNO_QUERY_THROW
);
1024 Reference
<XConfigurationController
> xCC(xCM
->getConfigurationController(),UNO_SET_THROW
);
1025 mxPane
.set(xCC
->getResource(rxViewId
->getAnchor()), UNO_QUERY_THROW
);
1027 mxWindow
= mxPane
->getWindow();
1028 mxCanvas
= mxPane
->getCanvas();
1030 mpToolBar
= new PresenterToolBar(
1034 rpPresenterController
,
1035 PresenterToolBar::Center
);
1036 mpToolBar
->Initialize("PresenterScreenSettings/ToolBars/ToolBar");
1040 mxWindow
->addPaintListener(this);
1042 Reference
<awt::XWindowPeer
> xPeer (mxWindow
, UNO_QUERY
);
1044 xPeer
->setBackground(util::Color(0xff000000));
1046 mxWindow
->setVisible(true);
1049 catch (RuntimeException
&)
1056 PresenterToolBarView::~PresenterToolBarView()
1060 void SAL_CALL
PresenterToolBarView::disposing()
1062 Reference
<lang::XComponent
> xComponent (static_cast<XWeak
*>(mpToolBar
.get()), UNO_QUERY
);
1063 mpToolBar
= nullptr;
1064 if (xComponent
.is())
1065 xComponent
->dispose();
1069 mxWindow
->removePaintListener(this);
1075 mpPresenterController
= nullptr;
1078 const ::rtl::Reference
<PresenterToolBar
>& PresenterToolBarView::GetPresenterToolBar() const
1083 //----- XPaintListener --------------------------------------------------------
1085 void SAL_CALL
PresenterToolBarView::windowPaint (const css::awt::PaintEvent
& rEvent
)
1087 awt::Rectangle
aWindowBox (mxWindow
->getPosSize());
1088 mpPresenterController
->GetCanvasHelper()->Paint(
1089 mpPresenterController
->GetViewBackground(mxViewId
->getResourceURL()),
1092 awt::Rectangle(0,0,aWindowBox
.Width
, aWindowBox
.Height
),
1096 //----- lang::XEventListener -------------------------------------------------
1098 void SAL_CALL
PresenterToolBarView::disposing (const lang::EventObject
& rEventObject
)
1100 if (rEventObject
.Source
== mxWindow
)
1104 //----- XResourceId -----------------------------------------------------------
1106 Reference
<XResourceId
> SAL_CALL
PresenterToolBarView::getResourceId()
1111 sal_Bool SAL_CALL
PresenterToolBarView::isAnchorOnly()
1116 //----- XDrawView -------------------------------------------------------------
1118 void SAL_CALL
PresenterToolBarView::setCurrentPage (const Reference
<drawing::XDrawPage
>& rxSlide
)
1120 Reference
<drawing::XDrawView
> xToolBar (static_cast<XWeak
*>(mpToolBar
.get()), UNO_QUERY
);
1122 xToolBar
->setCurrentPage(rxSlide
);
1125 Reference
<drawing::XDrawPage
> SAL_CALL
PresenterToolBarView::getCurrentPage()
1130 //===== PresenterToolBar::Element =============================================
1135 const ::rtl::Reference
<PresenterToolBar
>& rpToolBar
)
1136 : ElementInterfaceBase(m_aMutex
),
1137 mpToolBar(rpToolBar
),
1147 mbIsSelected(false),
1150 if (mpToolBar
.get() != nullptr)
1152 OSL_ASSERT(mpToolBar
->GetPresenterController().is());
1153 OSL_ASSERT(mpToolBar
->GetPresenterController()->GetWindowManager().is());
1157 void Element::SetModes (
1158 const SharedElementMode
& rpNormalMode
,
1159 const SharedElementMode
& rpMouseOverMode
,
1160 const SharedElementMode
& rpSelectedMode
,
1161 const SharedElementMode
& rpDisabledMode
)
1163 mpNormal
= rpNormalMode
;
1164 mpMouseOver
= rpMouseOverMode
;
1165 mpSelected
= rpSelectedMode
;
1166 mpDisabled
= rpDisabledMode
;
1167 mpMode
= rpNormalMode
;
1170 void Element::disposing()
1174 awt::Size
const & Element::GetBoundingSize (
1175 const Reference
<rendering::XCanvas
>& rxCanvas
)
1177 maSize
= CreateBoundingSize(rxCanvas
);
1181 awt::Rectangle
Element::GetBoundingBox() const
1183 return awt::Rectangle(maLocation
.X
,maLocation
.Y
, maSize
.Width
, maSize
.Height
);
1186 void Element::CurrentSlideHasChanged()
1191 void Element::SetLocation (const awt::Point
& rLocation
)
1193 maLocation
= rLocation
;
1196 void Element::SetSize (const geometry::RealSize2D
& rSize
)
1198 maSize
= awt::Size(sal_Int32(0.5+rSize
.Width
), sal_Int32(0.5+rSize
.Height
));
1201 bool Element::SetState (
1203 const bool bIsPressed
)
1205 bool bModified (mbIsOver
!= bIsOver
|| mbIsPressed
!= bIsPressed
);
1206 bool bClicked (mbIsPressed
&& bIsOver
&& ! bIsPressed
);
1209 mbIsPressed
= bIsPressed
;
1211 // When the element is disabled then ignore mouse over or selection.
1212 // When the element is selected then ignore mouse over.
1214 mpMode
= mpDisabled
;
1215 else if (mbIsSelected
)
1216 mpMode
= mpSelected
;
1218 mpMode
= mpMouseOver
;
1222 if (bClicked
&& mbIsEnabled
)
1224 if (mpMode
.get() != nullptr)
1228 if (mpMode
->msAction
.isEmpty())
1231 if (mpToolBar
.get() == nullptr)
1234 if (mpToolBar
->GetPresenterController().get() == nullptr)
1237 mpToolBar
->GetPresenterController()->DispatchUnoCommand(mpMode
->msAction
);
1238 mpToolBar
->RequestLayout();
1252 void Element::Invalidate (const bool bSynchronous
)
1254 OSL_ASSERT(mpToolBar
.is());
1255 mpToolBar
->InvalidateArea(GetBoundingBox(), bSynchronous
);
1258 bool Element::IsOutside (const awt::Rectangle
& rBox
)
1260 if (rBox
.X
>= maLocation
.X
+maSize
.Width
)
1262 else if (rBox
.Y
>= maLocation
.Y
+maSize
.Height
)
1264 else if (maLocation
.X
>= rBox
.X
+rBox
.Width
)
1266 else if (maLocation
.Y
>= rBox
.Y
+rBox
.Height
)
1273 bool Element::IsFilling() const
1278 void Element::UpdateState()
1280 OSL_ASSERT(mpToolBar
.get() != nullptr);
1281 OSL_ASSERT(mpToolBar
->GetPresenterController().get() != nullptr);
1283 if (mpMode
.get() == nullptr)
1286 util::URL
aURL (mpToolBar
->GetPresenterController()->CreateURLFromString(mpMode
->msAction
));
1287 Reference
<frame::XDispatch
> xDispatch (mpToolBar
->GetPresenterController()->GetDispatch(aURL
));
1290 xDispatch
->addStatusListener(this, aURL
);
1291 xDispatch
->removeStatusListener(this, aURL
);
1295 //----- lang::XEventListener --------------------------------------------------
1297 void SAL_CALL
Element::disposing (const css::lang::EventObject
&) {}
1299 //----- document::XEventListener ----------------------------------------------
1301 void SAL_CALL
Element::notifyEvent (const css::document::EventObject
&)
1306 //----- frame::XStatusListener ------------------------------------------------
1308 void SAL_CALL
Element::statusChanged (const css::frame::FeatureStateEvent
& rEvent
)
1310 bool bIsSelected (mbIsSelected
);
1311 bool bIsEnabled (rEvent
.IsEnabled
);
1312 rEvent
.State
>>= bIsSelected
;
1314 if (bIsSelected
!= mbIsSelected
|| bIsEnabled
!= mbIsEnabled
)
1316 mbIsEnabled
= bIsEnabled
;
1317 mbIsSelected
= bIsSelected
;
1318 SetState(mbIsOver
, mbIsPressed
);
1319 mpToolBar
->RequestLayout();
1323 } // end of anonymous namespace
1325 //===== ElementMode ===========================================================
1329 ElementMode::ElementMode()
1336 void ElementMode::ReadElementMode (
1337 const Reference
<beans::XPropertySet
>& rxElementProperties
,
1338 const OUString
& rsModeName
,
1339 std::shared_ptr
<ElementMode
> const & rpDefaultMode
,
1340 ::sdext::presenter::PresenterToolBar::Context
const & rContext
)
1344 Reference
<container::XHierarchicalNameAccess
> xNode (
1345 PresenterConfigurationAccess::GetProperty(rxElementProperties
, rsModeName
),
1347 Reference
<beans::XPropertySet
> xProperties (
1348 PresenterConfigurationAccess::GetNodeProperties(xNode
, OUString()));
1349 if (!xProperties
.is() && rpDefaultMode
!= nullptr)
1351 // The mode is not specified. Use the given, possibly empty,
1352 // default mode instead.
1353 mpIcon
= rpDefaultMode
->mpIcon
;
1354 msAction
= rpDefaultMode
->msAction
;
1355 maText
= rpDefaultMode
->maText
;
1359 if ( ! (PresenterConfigurationAccess::GetProperty(xProperties
, "Action") >>= msAction
))
1360 if (rpDefaultMode
!= nullptr)
1361 msAction
= rpDefaultMode
->msAction
;
1363 // Read text and font
1364 OUString
sText(rpDefaultMode
!= nullptr ? rpDefaultMode
->maText
.GetText() : OUString());
1365 PresenterConfigurationAccess::GetProperty(xProperties
, "Text") >>= sText
;
1366 Reference
<container::XHierarchicalNameAccess
> xFontNode (
1367 PresenterConfigurationAccess::GetProperty(xProperties
, "Font"), UNO_QUERY
);
1368 PresenterTheme::SharedFontDescriptor
pFont(PresenterTheme::ReadFont(
1369 xFontNode
, rpDefaultMode
!= nullptr ? rpDefaultMode
->maText
.GetFont()
1370 : PresenterTheme::SharedFontDescriptor()));
1371 maText
= Text(sText
,pFont
);
1373 // Read bitmaps to display as icons.
1374 Reference
<container::XHierarchicalNameAccess
> xIconNode (
1375 PresenterConfigurationAccess::GetProperty(xProperties
, "Icon"), UNO_QUERY
);
1376 mpIcon
= PresenterBitmapContainer::LoadBitmap(
1377 xIconNode
, "", rContext
.mxPresenterHelper
, rContext
.mxCanvas
,
1378 rpDefaultMode
!= nullptr ? rpDefaultMode
->mpIcon
: SharedBitmapDescriptor());
1386 } // end of anonymous namespace
1388 //===== Button ================================================================
1392 ::rtl::Reference
<Element
> Button::Create (
1393 const ::rtl::Reference
<PresenterToolBar
>& rpToolBar
)
1395 ::rtl::Reference
<Button
> pElement (new Button(rpToolBar
));
1396 pElement
->Initialize();
1397 return ::rtl::Reference
<Element
>(pElement
.get());
1401 const ::rtl::Reference
<PresenterToolBar
>& rpToolBar
)
1402 : Element(rpToolBar
),
1403 mbIsListenerRegistered(false)
1405 OSL_ASSERT(mpToolBar
.get() != nullptr);
1406 OSL_ASSERT(mpToolBar
->GetPresenterController().is());
1407 OSL_ASSERT(mpToolBar
->GetPresenterController()->GetWindowManager().is());
1410 void Button::Initialize()
1412 mpToolBar
->GetPresenterController()->GetWindowManager()->AddLayoutListener(this);
1413 mbIsListenerRegistered
= true;
1416 void Button::disposing()
1418 OSL_ASSERT(mpToolBar
.get() != nullptr);
1419 if (mpToolBar
.get() != nullptr
1420 && mbIsListenerRegistered
)
1422 OSL_ASSERT(mpToolBar
->GetPresenterController().is());
1423 OSL_ASSERT(mpToolBar
->GetPresenterController()->GetWindowManager().is());
1425 mbIsListenerRegistered
= false;
1426 mpToolBar
->GetPresenterController()->GetWindowManager()->RemoveLayoutListener(this);
1428 Element::disposing();
1431 void Button::Paint (
1432 const Reference
<rendering::XCanvas
>& rxCanvas
,
1433 const rendering::ViewState
& rViewState
)
1435 OSL_ASSERT(rxCanvas
.is());
1437 if (mpMode
.get() == nullptr)
1440 if (mpMode
->mpIcon
.get() == nullptr)
1443 geometry::RealRectangle2D
aTextBBox (mpMode
->maText
.GetBoundingBox(rxCanvas
));
1444 sal_Int32
nTextHeight (sal::static_int_cast
<sal_Int32
>(0.5 + aTextBBox
.Y2
- aTextBBox
.Y1
));
1446 PaintIcon(rxCanvas
, nTextHeight
, rViewState
);
1447 mpMode
->maText
.Paint(rxCanvas
, rViewState
, GetBoundingBox());
1450 awt::Size
Button::CreateBoundingSize (
1451 const Reference
<rendering::XCanvas
>& rxCanvas
)
1453 if (mpMode
.get() == nullptr)
1456 geometry::RealRectangle2D
aTextBBox (mpMode
->maText
.GetBoundingBox(rxCanvas
));
1457 const sal_Int32
nGap (5);
1458 sal_Int32
nTextHeight (sal::static_int_cast
<sal_Int32
>(0.5 + aTextBBox
.Y2
- aTextBBox
.Y1
));
1459 sal_Int32
nTextWidth (sal::static_int_cast
<sal_Int32
>(0.5 + aTextBBox
.X2
- aTextBBox
.X1
));
1460 Reference
<rendering::XBitmap
> xBitmap
;
1461 if (mpMode
->mpIcon
.get() != nullptr)
1462 xBitmap
= mpMode
->mpIcon
->GetNormalBitmap();
1465 geometry::IntegerSize2D
aSize (xBitmap
->getSize());
1467 ::std::max(aSize
.Width
, sal_Int32(0.5 + aTextBBox
.X2
- aTextBBox
.X1
)),
1468 aSize
.Height
+ nGap
+ nTextHeight
);
1471 return awt::Size(nTextWidth
,nTextHeight
);
1474 void Button::PaintIcon (
1475 const Reference
<rendering::XCanvas
>& rxCanvas
,
1476 const sal_Int32 nTextHeight
,
1477 const rendering::ViewState
& rViewState
)
1479 if (mpMode
.get() == nullptr)
1482 Reference
<rendering::XBitmap
> xBitmap (mpMode
->mpIcon
->GetBitmap(GetMode()));
1486 /// check whether RTL interface or not
1487 if(!AllSettings::GetLayoutRTL()){
1488 const sal_Int32
nX (maLocation
.X
1489 + (maSize
.Width
-xBitmap
->getSize().Width
) / 2);
1490 const sal_Int32
nY (maLocation
.Y
1491 + (maSize
.Height
- nTextHeight
- xBitmap
->getSize().Height
) / 2);
1492 const rendering::RenderState
aRenderState(
1493 geometry::AffineMatrix2D(1,0,nX
, 0,1,nY
),
1495 Sequence
<double>(4),
1496 rendering::CompositeOperation::OVER
);
1497 rxCanvas
->drawBitmap(xBitmap
, rViewState
, aRenderState
);
1500 const sal_Int32
nX (maLocation
.X
1501 + (maSize
.Width
+xBitmap
->getSize().Width
) / 2);
1502 const sal_Int32
nY (maLocation
.Y
1503 + (maSize
.Height
- nTextHeight
- xBitmap
->getSize().Height
) / 2);
1504 const rendering::RenderState
aRenderState(
1505 geometry::AffineMatrix2D(-1,0,nX
, 0,1,nY
),
1507 Sequence
<double>(4),
1508 rendering::CompositeOperation::OVER
);
1509 rxCanvas
->drawBitmap(xBitmap
, rViewState
, aRenderState
);
1513 PresenterBitmapDescriptor::Mode
Button::GetMode() const
1516 return PresenterBitmapDescriptor::Disabled
;
1517 else if (mbIsPressed
)
1518 return PresenterBitmapDescriptor::ButtonDown
;
1520 return PresenterBitmapDescriptor::MouseOver
;
1522 return PresenterBitmapDescriptor::Normal
;
1525 //----- lang::XEventListener --------------------------------------------------
1527 void SAL_CALL
Button::disposing (const css::lang::EventObject
& rEvent
)
1529 mbIsListenerRegistered
= false;
1530 Element::disposing(rEvent
);
1533 } // end of anonymous namespace
1535 //===== PresenterToolBar::Label ===============================================
1539 Label::Label (const ::rtl::Reference
<PresenterToolBar
>& rpToolBar
)
1540 : Element(rpToolBar
)
1544 awt::Size
Label::CreateBoundingSize (
1545 const Reference
<rendering::XCanvas
>& rxCanvas
)
1547 if (mpMode
.get() == nullptr)
1548 return awt::Size(0,0);
1550 geometry::RealRectangle2D
aTextBBox (mpMode
->maText
.GetBoundingBox(rxCanvas
));
1552 sal::static_int_cast
<sal_Int32
>(0.5 + aTextBBox
.X2
- aTextBBox
.X1
),
1553 sal::static_int_cast
<sal_Int32
>(0.5 + aTextBBox
.Y2
- aTextBBox
.Y1
));
1556 void Label::SetText (const OUString
& rsText
)
1558 OSL_ASSERT(mpToolBar
.get() != nullptr);
1559 if (mpMode
.get() == nullptr)
1562 const bool bRequestLayout (mpMode
->maText
.GetText().getLength() != rsText
.getLength());
1564 mpMode
->maText
.SetText(rsText
);
1565 // Just use the character count for determining whether a layout is
1566 // necessary. This is an optimization to avoid layouts every time a new
1567 // time value is set on some labels.
1569 mpToolBar
->RequestLayout();
1575 const Reference
<rendering::XCanvas
>& rxCanvas
,
1576 const rendering::ViewState
& rViewState
)
1578 OSL_ASSERT(rxCanvas
.is());
1579 if (mpMode
.get() == nullptr)
1582 mpMode
->maText
.Paint(rxCanvas
, rViewState
, GetBoundingBox());
1585 bool Label::SetState (const bool, const bool)
1587 // For labels there is no mouse over effect.
1588 return Element::SetState(false, false);
1591 } // end of anonymous namespace
1593 //===== Text ==================================================================
1604 const OUString
& rsText
,
1605 const PresenterTheme::SharedFontDescriptor
& rpFont
)
1611 void Text::SetText (const OUString
& rsText
)
1616 const OUString
& Text::GetText() const
1621 const PresenterTheme::SharedFontDescriptor
& Text::GetFont() const
1627 const Reference
<rendering::XCanvas
>& rxCanvas
,
1628 const rendering::ViewState
& rViewState
,
1629 const awt::Rectangle
& rBoundingBox
)
1631 OSL_ASSERT(rxCanvas
.is());
1633 if (msText
.isEmpty())
1635 if (mpFont
.get() == nullptr)
1638 if ( ! mpFont
->mxFont
.is())
1639 mpFont
->PrepareFont(rxCanvas
);
1640 if ( ! mpFont
->mxFont
.is())
1643 rendering::StringContext
aContext (msText
, 0, msText
.getLength());
1645 Reference
<rendering::XTextLayout
> xLayout (
1646 mpFont
->mxFont
->createTextLayout(
1648 rendering::TextDirection::WEAK_LEFT_TO_RIGHT
,
1650 geometry::RealRectangle2D
aBox (xLayout
->queryTextBounds());
1651 const double nTextWidth
= aBox
.X2
- aBox
.X1
;
1652 const double nY
= rBoundingBox
.Y
+ rBoundingBox
.Height
- aBox
.Y2
;
1653 const double nX
= rBoundingBox
.X
+ (rBoundingBox
.Width
- nTextWidth
)/2;
1655 rendering::RenderState
aRenderState(
1656 geometry::AffineMatrix2D(1,0,nX
, 0,1,nY
),
1658 Sequence
<double>(4),
1659 rendering::CompositeOperation::SOURCE
);
1660 PresenterCanvasHelper::SetDeviceColor(aRenderState
, mpFont
->mnColor
);
1661 rxCanvas
->drawTextLayout(
1667 geometry::RealRectangle2D
Text::GetBoundingBox (const Reference
<rendering::XCanvas
>& rxCanvas
)
1669 if (mpFont
.get() != nullptr && !msText
.isEmpty())
1671 if ( ! mpFont
->mxFont
.is())
1672 mpFont
->PrepareFont(rxCanvas
);
1673 if (mpFont
->mxFont
.is())
1675 rendering::StringContext
aContext (msText
, 0, msText
.getLength());
1676 Reference
<rendering::XTextLayout
> xLayout (
1677 mpFont
->mxFont
->createTextLayout(
1679 rendering::TextDirection::WEAK_LEFT_TO_RIGHT
,
1681 return xLayout
->queryTextBounds();
1684 return geometry::RealRectangle2D(0,0,0,0);
1687 //===== TimeFormatter =========================================================
1689 OUString
TimeFormatter::FormatTime (const oslDateTime
& rTime
)
1691 OUStringBuffer sText
;
1693 const sal_Int32
nHours (sal::static_int_cast
<sal_Int32
>(rTime
.Hours
));
1694 const sal_Int32
nMinutes (sal::static_int_cast
<sal_Int32
>(rTime
.Minutes
));
1695 const sal_Int32
nSeconds(sal::static_int_cast
<sal_Int32
>(rTime
.Seconds
));
1697 sText
.append(OUString::number(nHours
));
1702 const OUString
sMinutes (OUString::number(nMinutes
));
1703 if (sMinutes
.getLength() == 1)
1705 sText
.append(sMinutes
);
1709 const OUString
sSeconds (OUString::number(nSeconds
));
1710 if (sSeconds
.getLength() == 1)
1712 sText
.append(sSeconds
);
1713 return sText
.makeStringAndClear();
1716 //===== TimeLabel =============================================================
1718 TimeLabel::TimeLabel (const ::rtl::Reference
<PresenterToolBar
>& rpToolBar
)
1724 void SAL_CALL
TimeLabel::disposing()
1726 PresenterClockTimer::Instance(mpToolBar
->GetComponentContext())->RemoveListener(mpListener
);
1730 void TimeLabel::ConnectToTimer()
1732 mpListener
.reset(new Listener(this));
1733 PresenterClockTimer::Instance(mpToolBar
->GetComponentContext())->AddListener(mpListener
);
1736 //===== CurrentTimeLabel ======================================================
1738 ::rtl::Reference
<Element
> CurrentTimeLabel::Create (
1739 const ::rtl::Reference
<PresenterToolBar
>& rpToolBar
)
1741 ::rtl::Reference
<TimeLabel
> pElement(new CurrentTimeLabel(rpToolBar
));
1742 pElement
->ConnectToTimer();
1743 return ::rtl::Reference
<Element
>(pElement
.get());
1746 CurrentTimeLabel::~CurrentTimeLabel()
1750 CurrentTimeLabel::CurrentTimeLabel (
1751 const ::rtl::Reference
<PresenterToolBar
>& rpToolBar
)
1752 : TimeLabel(rpToolBar
)
1756 void CurrentTimeLabel::TimeHasChanged (const oslDateTime
& rCurrentTime
)
1758 SetText(TimeFormatter::FormatTime(rCurrentTime
));
1762 void CurrentTimeLabel::SetModes (
1763 const SharedElementMode
& rpNormalMode
,
1764 const SharedElementMode
& rpMouseOverMode
,
1765 const SharedElementMode
& rpSelectedMode
,
1766 const SharedElementMode
& rpDisabledMode
)
1768 TimeLabel::SetModes(rpNormalMode
, rpMouseOverMode
, rpSelectedMode
, rpDisabledMode
);
1769 SetText(TimeFormatter::FormatTime(PresenterClockTimer::GetCurrentTime()));
1772 //===== PresentationTimeLabel =================================================
1774 ::rtl::Reference
<Element
> PresentationTimeLabel::Create (
1775 const ::rtl::Reference
<PresenterToolBar
>& rpToolBar
)
1777 ::rtl::Reference
<TimeLabel
> pElement(new PresentationTimeLabel(rpToolBar
));
1778 pElement
->ConnectToTimer();
1779 return ::rtl::Reference
<Element
>(pElement
.get());
1782 PresentationTimeLabel::~PresentationTimeLabel()
1784 mpToolBar
->GetPresenterController()->SetPresentationTime(nullptr);
1787 PresentationTimeLabel::PresentationTimeLabel (
1788 const ::rtl::Reference
<PresenterToolBar
>& rpToolBar
)
1789 : TimeLabel(rpToolBar
),
1793 mpToolBar
->GetPresenterController()->SetPresentationTime(this);
1796 void PresentationTimeLabel::restart()
1798 maStartTimeValue
.Seconds
= 0;
1799 maStartTimeValue
.Nanosec
= 0;
1802 void PresentationTimeLabel::TimeHasChanged (const oslDateTime
& rCurrentTime
)
1804 TimeValue aCurrentTimeValue
;
1805 if (!osl_getTimeValueFromDateTime(&rCurrentTime
, &aCurrentTimeValue
))
1808 if (maStartTimeValue
.Seconds
==0 && maStartTimeValue
.Nanosec
==0)
1810 // This method is called for the first time. Initialize the
1811 // start time. The start time is rounded to nearest second to
1812 // keep the time updates synchronized with the current time label.
1813 maStartTimeValue
= aCurrentTimeValue
;
1814 if (maStartTimeValue
.Nanosec
>= 500000000)
1815 maStartTimeValue
.Seconds
+= 1;
1816 maStartTimeValue
.Nanosec
= 0;
1819 TimeValue aElapsedTimeValue
;
1820 aElapsedTimeValue
.Seconds
= aCurrentTimeValue
.Seconds
- maStartTimeValue
.Seconds
;
1821 aElapsedTimeValue
.Nanosec
= aCurrentTimeValue
.Nanosec
- maStartTimeValue
.Nanosec
;
1823 oslDateTime aElapsedDateTime
;
1824 if (osl_getDateTimeFromTimeValue(&aElapsedTimeValue
, &aElapsedDateTime
))
1826 SetText(TimeFormatter::FormatTime(aElapsedDateTime
));
1831 void PresentationTimeLabel::SetModes (
1832 const SharedElementMode
& rpNormalMode
,
1833 const SharedElementMode
& rpMouseOverMode
,
1834 const SharedElementMode
& rpSelectedMode
,
1835 const SharedElementMode
& rpDisabledMode
)
1837 TimeLabel::SetModes(rpNormalMode
, rpMouseOverMode
, rpSelectedMode
, rpDisabledMode
);
1839 oslDateTime aStartDateTime
;
1840 if (osl_getDateTimeFromTimeValue(&maStartTimeValue
, &aStartDateTime
))
1842 SetText(TimeFormatter::FormatTime(aStartDateTime
));
1846 //===== VerticalSeparator =====================================================
1848 VerticalSeparator::VerticalSeparator (
1849 const ::rtl::Reference
<PresenterToolBar
>& rpToolBar
)
1850 : Element(rpToolBar
)
1854 void VerticalSeparator::Paint (
1855 const Reference
<rendering::XCanvas
>& rxCanvas
,
1856 const rendering::ViewState
& rViewState
)
1858 OSL_ASSERT(rxCanvas
.is());
1860 awt::Rectangle
aBBox (GetBoundingBox());
1862 rendering::RenderState
aRenderState(
1863 geometry::AffineMatrix2D(1,0,0, 0,1,0),
1865 Sequence
<double>(4),
1866 rendering::CompositeOperation::OVER
);
1867 if (mpMode
.get() != nullptr)
1869 PresenterTheme::SharedFontDescriptor
pFont (mpMode
->maText
.GetFont());
1870 if (pFont
.get() != nullptr)
1871 PresenterCanvasHelper::SetDeviceColor(aRenderState
, pFont
->mnColor
);
1874 rxCanvas
->fillPolyPolygon(
1875 PresenterGeometryHelper::CreatePolygon(aBBox
, rxCanvas
->getDevice()),
1880 awt::Size
VerticalSeparator::CreateBoundingSize (
1881 const Reference
<rendering::XCanvas
>&)
1883 return awt::Size(1,20);
1886 bool VerticalSeparator::IsFilling() const
1891 //===== HorizontalSeparator ===================================================
1893 HorizontalSeparator::HorizontalSeparator (
1894 const ::rtl::Reference
<PresenterToolBar
>& rpToolBar
)
1895 : Element(rpToolBar
)
1899 void HorizontalSeparator::Paint (
1900 const Reference
<rendering::XCanvas
>& rxCanvas
,
1901 const rendering::ViewState
& rViewState
)
1903 OSL_ASSERT(rxCanvas
.is());
1905 awt::Rectangle
aBBox (GetBoundingBox());
1907 rendering::RenderState
aRenderState(
1908 geometry::AffineMatrix2D(1,0,0, 0,1,0),
1910 Sequence
<double>(4),
1911 rendering::CompositeOperation::OVER
);
1912 if (mpMode
.get() != nullptr)
1914 PresenterTheme::SharedFontDescriptor
pFont (mpMode
->maText
.GetFont());
1915 if (pFont
.get() != nullptr)
1916 PresenterCanvasHelper::SetDeviceColor(aRenderState
, pFont
->mnColor
);
1919 rxCanvas
->fillPolyPolygon(
1920 PresenterGeometryHelper::CreatePolygon(aBBox
, rxCanvas
->getDevice()),
1925 awt::Size
HorizontalSeparator::CreateBoundingSize (
1926 const Reference
<rendering::XCanvas
>&)
1928 return awt::Size(20,1);
1931 bool HorizontalSeparator::IsFilling() const
1936 } // end of anonymous namespace
1938 } } // end of namespace ::sdext::presenter
1940 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */