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 .
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 "PresenterTimer.hxx"
29 #include "PresenterWindowManager.hxx"
30 #include <DrawController.hxx>
32 #include <cppuhelper/compbase.hxx>
33 #include <com/sun/star/awt/XWindowPeer.hpp>
34 #include <com/sun/star/drawing/framework/XConfigurationController.hpp>
35 #include <com/sun/star/drawing/framework/XPane.hpp>
36 #include <com/sun/star/geometry/AffineMatrix2D.hpp>
37 #include <com/sun/star/rendering/CompositeOperation.hpp>
38 #include <com/sun/star/rendering/RenderState.hpp>
39 #include <com/sun/star/rendering/TextDirection.hpp>
40 #include <com/sun/star/rendering/ViewState.hpp>
41 #include <com/sun/star/rendering/XSpriteCanvas.hpp>
42 #include <com/sun/star/util/Color.hpp>
43 #include <rtl/ustrbuf.hxx>
45 using namespace ::com::sun::star
;
46 using namespace ::com::sun::star::uno
;
47 using namespace ::com::sun::star::drawing::framework
;
49 namespace sdext::presenter
{
51 const sal_Int32
gnGapSize (20);
61 PresenterTheme::SharedFontDescriptor pFont
);
63 void SetText (const OUString
& rsText
);
64 const OUString
& GetText() const;
65 const PresenterTheme::SharedFontDescriptor
& GetFont() const;
68 const Reference
<rendering::XCanvas
>& rxCanvas
,
69 const rendering::ViewState
& rViewState
,
70 const awt::Rectangle
& rBoundingBox
);
72 geometry::RealRectangle2D
GetBoundingBox (
73 const Reference
<rendering::XCanvas
>& rxCanvas
);
77 PresenterTheme::SharedFontDescriptor mpFont
;
84 ElementMode(const ElementMode
&) = delete;
85 ElementMode
& operator=(const ElementMode
&) = delete;
87 SharedBitmapDescriptor mpIcon
;
91 void ReadElementMode (
92 const Reference
<beans::XPropertySet
>& rxProperties
,
93 const OUString
& rsModeName
,
94 std::shared_ptr
<ElementMode
> const & rpDefaultMode
,
95 ::sdext::presenter::PresenterToolBar::Context
const & rContext
);
97 typedef std::shared_ptr
<ElementMode
> SharedElementMode
;
99 } // end of anonymous namespace
101 class PresenterToolBar::Context
105 Context(const Context
&) = delete;
106 Context
& operator=(const Context
&) = delete;
107 Reference
<drawing::XPresenterHelper
> mxPresenterHelper
;
108 css::uno::Reference
<css::rendering::XCanvas
> mxCanvas
;
111 //===== PresenterToolBar::Element =============================================
114 typedef cppu::WeakComponentImplHelper
<
115 css::document::XEventListener
,
116 css::frame::XStatusListener
117 > ElementInterfaceBase
;
120 : private ::cppu::BaseMutex
,
121 public ElementInterfaceBase
124 explicit Element (::rtl::Reference
<PresenterToolBar
> pToolBar
);
125 Element(const Element
&) = delete;
126 Element
& operator=(const Element
&) = delete;
128 virtual void SAL_CALL
disposing() override
;
130 virtual void SetModes (
131 const SharedElementMode
& rpNormalMode
,
132 const SharedElementMode
& rpMouseOverMode
,
133 const SharedElementMode
& rpSelectedMode
,
134 const SharedElementMode
& rpDisabledMode
,
135 const SharedElementMode
& rpMouseOverSelectedMode
);
136 void CurrentSlideHasChanged();
137 void SetLocation (const awt::Point
& rLocation
);
138 void SetSize (const geometry::RealSize2D
& rSize
);
140 const Reference
<rendering::XCanvas
>& rxCanvas
,
141 const rendering::ViewState
& rViewState
) = 0;
142 awt::Size
const & GetBoundingSize (
143 const Reference
<rendering::XCanvas
>& rxCanvas
);
144 awt::Rectangle
GetBoundingBox() const;
145 virtual bool SetState (const bool bIsOver
, const bool bIsPressed
);
146 void Invalidate (const bool bSynchronous
);
147 bool IsOutside (const awt::Rectangle
& rBox
);
148 virtual bool IsFilling() const;
151 // lang::XEventListener
153 virtual void SAL_CALL
disposing (const css::lang::EventObject
& rEvent
) override
;
155 // document::XEventListener
157 virtual void SAL_CALL
notifyEvent (const css::document::EventObject
& rEvent
) override
;
159 // frame::XStatusListener
161 virtual void SAL_CALL
statusChanged (const css::frame::FeatureStateEvent
& rEvent
) override
;
164 ::rtl::Reference
<PresenterToolBar
> mpToolBar
;
165 awt::Point maLocation
;
167 SharedElementMode mpNormal
;
168 SharedElementMode mpMouseOver
;
169 SharedElementMode mpSelected
;
170 SharedElementMode mpDisabled
;
171 SharedElementMode mpMouseOverSelected
;
172 SharedElementMode mpMode
;
177 virtual awt::Size
CreateBoundingSize (
178 const Reference
<rendering::XCanvas
>& rxCanvas
) = 0;
180 bool IsEnabled() const { return mbIsEnabled
;}
185 } // end of anonymous namespace
187 class PresenterToolBar::ElementContainerPart
188 : public ::std::vector
<rtl::Reference
<Element
> >
192 //===== Button ================================================================
196 class Button
: public Element
199 static ::rtl::Reference
<Element
> Create (
200 const ::rtl::Reference
<PresenterToolBar
>& rpToolBar
);
202 virtual void SAL_CALL
disposing() override
;
205 const Reference
<rendering::XCanvas
>& rxCanvas
,
206 const rendering::ViewState
& rViewState
) override
;
208 // lang::XEventListener
210 virtual void SAL_CALL
disposing (const css::lang::EventObject
& rEvent
) override
;
213 virtual awt::Size
CreateBoundingSize (
214 const Reference
<rendering::XCanvas
>& rxCanvas
) override
;
217 bool mbIsListenerRegistered
;
219 Button (const ::rtl::Reference
<PresenterToolBar
>& rpToolBar
);
222 const Reference
<rendering::XCanvas
>& rxCanvas
,
223 const sal_Int32 nTextHeight
,
224 const rendering::ViewState
& rViewState
);
225 PresenterBitmapDescriptor::Mode
GetMode() const;
228 //===== Label =================================================================
230 class Label
: public Element
233 explicit Label (const ::rtl::Reference
<PresenterToolBar
>& rpToolBar
);
235 void SetText (const OUString
& rsText
);
237 const Reference
<rendering::XCanvas
>& rxCanvas
,
238 const rendering::ViewState
& rViewState
) override
;
239 virtual bool SetState (const bool bIsOver
, const bool bIsPressed
) override
;
242 virtual awt::Size
CreateBoundingSize (
243 const Reference
<rendering::XCanvas
>& rxCanvas
) override
;
246 // Some specialized controls.
251 static OUString
FormatTime (const oslDateTime
& rTime
);
254 class TimeLabel
: public Label
257 void ConnectToTimer();
258 virtual void TimeHasChanged (const oslDateTime
& rCurrentTime
) = 0;
260 explicit TimeLabel(const ::rtl::Reference
<PresenterToolBar
>& rpToolBar
);
261 using Element::disposing
;
262 virtual void SAL_CALL
disposing() override
;
264 class Listener
: public PresenterClockTimer::Listener
267 explicit Listener (::rtl::Reference
<TimeLabel
> xLabel
)
268 : mxLabel(std::move(xLabel
)) {}
269 virtual ~Listener() {}
270 virtual void TimeHasChanged (const oslDateTime
& rCurrentTime
) override
271 { if (mxLabel
.is()) mxLabel
->TimeHasChanged(rCurrentTime
); }
273 ::rtl::Reference
<TimeLabel
> mxLabel
;
275 std::shared_ptr
<PresenterClockTimer::Listener
> mpListener
;
278 class CurrentTimeLabel
: public TimeLabel
281 static ::rtl::Reference
<Element
> Create (
282 const ::rtl::Reference
<PresenterToolBar
>& rpToolBar
);
283 virtual void SetModes (
284 const SharedElementMode
& rpNormalMode
,
285 const SharedElementMode
& rpMouseOverMode
,
286 const SharedElementMode
& rpSelectedMode
,
287 const SharedElementMode
& rpDisabledMode
,
288 const SharedElementMode
& rpMouseOverSelectedMode
) override
;
290 CurrentTimeLabel (const ::rtl::Reference
<PresenterToolBar
>& rpToolBar
);
291 virtual ~CurrentTimeLabel() override
;
292 virtual void TimeHasChanged (const oslDateTime
& rCurrentTime
) override
;
295 class PresentationTimeLabel
: public TimeLabel
, public IPresentationTime
298 static ::rtl::Reference
<Element
> Create (
299 const ::rtl::Reference
<PresenterToolBar
>& rpToolBar
);
300 virtual void SetModes (
301 const SharedElementMode
& rpNormalMode
,
302 const SharedElementMode
& rpMouseOverMode
,
303 const SharedElementMode
& rpSelectedMode
,
304 const SharedElementMode
& rpDisabledMode
,
305 const SharedElementMode
& rpMouseOverSelectedMode
) override
;
306 virtual void restart() override
;
307 virtual bool isPaused() override
;
308 virtual void setPauseStatus(const bool pauseStatus
) override
;
309 const TimeValue
& getPauseTimeValue() const;
310 void setPauseTimeValue(const TimeValue pauseTime
);
312 TimeValue maStartTimeValue
;
313 TimeValue pauseTimeValue
;
314 PresentationTimeLabel (const ::rtl::Reference
<PresenterToolBar
>& rpToolBar
);
316 virtual ~PresentationTimeLabel() override
;
317 virtual void TimeHasChanged (const oslDateTime
& rCurrentTime
) override
;
320 class VerticalSeparator
: public Element
323 explicit VerticalSeparator (const ::rtl::Reference
<PresenterToolBar
>& rpToolBar
);
325 const Reference
<rendering::XCanvas
>& rxCanvas
,
326 const rendering::ViewState
& rViewState
) override
;
327 virtual bool IsFilling() const override
;
330 virtual awt::Size
CreateBoundingSize (
331 const Reference
<rendering::XCanvas
>& rxCanvas
) override
;
334 class HorizontalSeparator
: public Element
337 explicit HorizontalSeparator (const ::rtl::Reference
<PresenterToolBar
>& rpToolBar
);
339 const Reference
<rendering::XCanvas
>& rxCanvas
,
340 const rendering::ViewState
& rViewState
) override
;
341 virtual bool IsFilling() const override
;
344 virtual awt::Size
CreateBoundingSize (
345 const Reference
<rendering::XCanvas
>& rxCanvas
) override
;
347 } // end of anonymous namespace
349 //===== PresenterToolBar ======================================================
351 PresenterToolBar::PresenterToolBar (
352 const Reference
<XComponentContext
>& rxContext
,
353 css::uno::Reference
<css::awt::XWindow
> xWindow
,
354 css::uno::Reference
<css::rendering::XCanvas
> xCanvas
,
355 ::rtl::Reference
<PresenterController
> pPresenterController
,
356 const Anchor eAnchor
)
357 : PresenterToolBarInterfaceBase(m_aMutex
),
358 mxComponentContext(rxContext
),
359 mxWindow(std::move(xWindow
)),
360 mxCanvas(std::move(xCanvas
)),
361 mpPresenterController(std::move(pPresenterController
)),
362 mbIsLayoutPending(false),
367 void PresenterToolBar::Initialize (
368 const OUString
& rsConfigurationPath
)
372 CreateControls(rsConfigurationPath
);
376 mxWindow
->addWindowListener(this);
377 mxWindow
->addPaintListener(this);
378 mxWindow
->addMouseListener(this);
379 mxWindow
->addMouseMotionListener(this);
381 Reference
<awt::XWindowPeer
> xPeer (mxWindow
, UNO_QUERY
);
383 xPeer
->setBackground(util::Color(0xff000000));
385 mxWindow
->setVisible(true);
388 mxSlideShowController
= mpPresenterController
->GetSlideShowController();
390 mbIsLayoutPending
= true;
392 catch (RuntimeException
&)
394 mpCurrentContainerPart
.reset();
395 maElementContainer
.clear();
400 PresenterToolBar::~PresenterToolBar()
404 void SAL_CALL
PresenterToolBar::disposing()
408 mxWindow
->removeWindowListener(this);
409 mxWindow
->removePaintListener(this);
410 mxWindow
->removeMouseListener(this);
411 mxWindow
->removeMouseMotionListener(this);
415 // Dispose tool bar elements.
416 for (const auto& rxPart
: maElementContainer
)
418 OSL_ASSERT(rxPart
!= nullptr);
419 for (const rtl::Reference
<Element
>& pElement
: *rxPart
)
423 Reference
<lang::XComponent
> xComponent
= pElement
;
425 xComponent
->dispose();
430 mpCurrentContainerPart
.reset();
431 maElementContainer
.clear();
434 void PresenterToolBar::InvalidateArea (
435 const awt::Rectangle
& rRepaintBox
,
436 const bool bSynchronous
)
438 std::shared_ptr
<PresenterPaintManager
> xManager(mpPresenterController
->GetPaintManager());
441 xManager
->Invalidate(
447 void PresenterToolBar::RequestLayout()
449 mbIsLayoutPending
= true;
451 std::shared_ptr
<PresenterPaintManager
> xManager(mpPresenterController
->GetPaintManager());
455 xManager
->Invalidate(mxWindow
);
458 geometry::RealSize2D
const & PresenterToolBar::GetMinimalSize()
460 if (mbIsLayoutPending
)
462 return maMinimalSize
;
465 const ::rtl::Reference
<PresenterController
>& PresenterToolBar::GetPresenterController() const
467 return mpPresenterController
;
470 const Reference
<XComponentContext
>& PresenterToolBar::GetComponentContext() const
472 return mxComponentContext
;
475 //----- lang::XEventListener -------------------------------------------------
477 void SAL_CALL
PresenterToolBar::disposing (const lang::EventObject
& rEventObject
)
479 if (rEventObject
.Source
== mxWindow
)
483 //----- XWindowListener -------------------------------------------------------
485 void SAL_CALL
PresenterToolBar::windowResized (const awt::WindowEvent
&)
487 mbIsLayoutPending
= true;
490 void SAL_CALL
PresenterToolBar::windowMoved (const awt::WindowEvent
&) {}
492 void SAL_CALL
PresenterToolBar::windowShown (const lang::EventObject
&)
494 mbIsLayoutPending
= true;
497 void SAL_CALL
PresenterToolBar::windowHidden (const lang::EventObject
&) {}
499 //----- XPaintListener --------------------------------------------------------
500 void SAL_CALL
PresenterToolBar::windowPaint (const css::awt::PaintEvent
& rEvent
)
502 if ( ! mxCanvas
.is())
505 if ( ! mbIsPresenterViewActive
)
508 const rendering::ViewState
aViewState (
509 geometry::AffineMatrix2D(1,0,0, 0,1,0),
510 PresenterGeometryHelper::CreatePolygon(rEvent
.UpdateRect
, mxCanvas
->getDevice()));
512 if (mbIsLayoutPending
)
515 Paint(rEvent
.UpdateRect
, aViewState
);
517 // Make the back buffer visible.
518 Reference
<rendering::XSpriteCanvas
> xSpriteCanvas (mxCanvas
, UNO_QUERY
);
519 if (xSpriteCanvas
.is())
520 xSpriteCanvas
->updateScreen(false);
523 //----- XMouseListener --------------------------------------------------------
524 void SAL_CALL
PresenterToolBar::mousePressed (const css::awt::MouseEvent
& rEvent
)
527 CheckMouseOver(rEvent
, true, true);
530 void SAL_CALL
PresenterToolBar::mouseReleased (const css::awt::MouseEvent
& rEvent
)
533 CheckMouseOver(rEvent
, true);
536 void SAL_CALL
PresenterToolBar::mouseEntered (const css::awt::MouseEvent
& rEvent
)
539 CheckMouseOver(rEvent
, true);
542 void SAL_CALL
PresenterToolBar::mouseExited (const css::awt::MouseEvent
& rEvent
)
545 CheckMouseOver(rEvent
, false);
548 //----- XMouseMotionListener --------------------------------------------------
550 void SAL_CALL
PresenterToolBar::mouseMoved (const css::awt::MouseEvent
& rEvent
)
553 CheckMouseOver(rEvent
, true);
556 void SAL_CALL
PresenterToolBar::mouseDragged (const css::awt::MouseEvent
&)
561 //----- XDrawView -------------------------------------------------------------
563 void SAL_CALL
PresenterToolBar::setCurrentPage (const Reference
<drawing::XDrawPage
>& rxSlide
)
565 if (rxSlide
!= mxCurrentSlide
)
567 mxCurrentSlide
= rxSlide
;
572 Reference
<drawing::XDrawPage
> SAL_CALL
PresenterToolBar::getCurrentPage()
574 return mxCurrentSlide
;
578 void PresenterToolBar::CreateControls (
579 const OUString
& rsConfigurationPath
)
581 if ( ! mxWindow
.is())
584 // Expand the macro in the bitmap file names.
585 PresenterConfigurationAccess
aConfiguration (
587 "/org.openoffice.Office.PresenterScreen/",
588 PresenterConfigurationAccess::READ_ONLY
);
590 mpCurrentContainerPart
= std::make_shared
<ElementContainerPart
>();
591 maElementContainer
.clear();
592 maElementContainer
.push_back(mpCurrentContainerPart
);
594 Reference
<container::XHierarchicalNameAccess
> xToolBarNode (
595 aConfiguration
.GetConfigurationNode(rsConfigurationPath
),
597 if (!xToolBarNode
.is())
600 Reference
<container::XNameAccess
> xEntries (
601 PresenterConfigurationAccess::GetConfigurationNode(xToolBarNode
, "Entries"),
604 aContext
.mxPresenterHelper
= mpPresenterController
->GetPresenterHelper();
605 aContext
.mxCanvas
= mxCanvas
;
607 && aContext
.mxPresenterHelper
.is()
608 && aContext
.mxCanvas
.is())
610 PresenterConfigurationAccess::ForAll(
612 [this, &aContext
] (OUString
const&, uno::Reference
<beans::XPropertySet
> const& xProps
)
614 return this->ProcessEntry(xProps
, aContext
);
619 void PresenterToolBar::ProcessEntry (
620 const Reference
<beans::XPropertySet
>& rxProperties
,
621 Context
const & rContext
)
623 if ( ! rxProperties
.is())
626 // Type has to be present.
628 if ( ! (PresenterConfigurationAccess::GetProperty(rxProperties
, "Type") >>= sType
))
631 // Read mode specific values.
632 SharedElementMode pNormalMode
= std::make_shared
<ElementMode
>();
633 SharedElementMode pMouseOverMode
= std::make_shared
<ElementMode
>();
634 SharedElementMode pSelectedMode
= std::make_shared
<ElementMode
>();
635 SharedElementMode pDisabledMode
= std::make_shared
<ElementMode
>();
636 SharedElementMode pMouseOverSelectedMode
= std::make_shared
<ElementMode
>();
637 pNormalMode
->ReadElementMode(rxProperties
, "Normal", pNormalMode
, rContext
);
638 pMouseOverMode
->ReadElementMode(rxProperties
, "MouseOver", pNormalMode
, rContext
);
639 pSelectedMode
->ReadElementMode(rxProperties
, "Selected", pNormalMode
, rContext
);
640 pDisabledMode
->ReadElementMode(rxProperties
, "Disabled", pNormalMode
, rContext
);
641 pMouseOverSelectedMode
->ReadElementMode(rxProperties
, "MouseOverSelected", pSelectedMode
, rContext
);
643 // Create new element.
644 ::rtl::Reference
<Element
> pElement
;
645 if ( sType
== "Button" )
646 pElement
= Button::Create(this);
647 else if ( sType
== "CurrentTimeLabel" )
648 pElement
= CurrentTimeLabel::Create(this);
649 else if ( sType
== "PresentationTimeLabel" )
650 pElement
= PresentationTimeLabel::Create(this);
651 else if ( sType
== "VerticalSeparator" )
652 pElement
.set(new VerticalSeparator(this));
653 else if ( sType
== "HorizontalSeparator" )
654 pElement
.set(new HorizontalSeparator(this));
655 else if ( sType
== "Label" )
656 pElement
.set(new Label(this));
657 else if ( sType
== "ChangeOrientation" )
659 mpCurrentContainerPart
= std::make_shared
<ElementContainerPart
>();
660 maElementContainer
.push_back(mpCurrentContainerPart
);
665 pElement
->SetModes( pNormalMode
, pMouseOverMode
, pSelectedMode
, pDisabledMode
, pMouseOverSelectedMode
);
666 pElement
->UpdateState();
667 if (mpCurrentContainerPart
)
668 mpCurrentContainerPart
->push_back(pElement
);
672 void PresenterToolBar::Layout (
673 const Reference
<rendering::XCanvas
>& rxCanvas
)
675 if (maElementContainer
.empty())
678 mbIsLayoutPending
= false;
680 const awt::Rectangle
aWindowBox (mxWindow
->getPosSize());
681 ::std::vector
<geometry::RealSize2D
> aPartSizes (maElementContainer
.size());
682 geometry::RealSize2D
aTotalSize (0,0);
683 bool bIsHorizontal (true);
684 sal_Int32
nIndex (0);
685 double nTotalHorizontalGap (0);
686 sal_Int32
nGapCount (0);
687 for (const auto& rxPart
: maElementContainer
)
689 geometry::RealSize2D
aSize (CalculatePartSize(rxCanvas
, rxPart
, bIsHorizontal
));
691 // Remember the size of each part for later.
692 aPartSizes
[nIndex
] = aSize
;
694 // Add gaps between elements.
695 if (rxPart
->size()>1 && bIsHorizontal
)
697 nTotalHorizontalGap
+= (rxPart
->size() - 1) * gnGapSize
;
698 nGapCount
+= rxPart
->size() - 1;
701 // Orientation changes for each part.
702 bIsHorizontal
= !bIsHorizontal
;
703 // Width is accumulated.
704 aTotalSize
.Width
+= aSize
.Width
;
705 // Height is the maximum height of all parts.
706 aTotalSize
.Height
= ::std::max(aTotalSize
.Height
, aSize
.Height
);
709 // Add gaps between parts.
710 if (maElementContainer
.size() > 1)
712 nTotalHorizontalGap
+= (maElementContainer
.size() - 1) * gnGapSize
;
713 nGapCount
+= maElementContainer
.size()-1;
716 // Done to introduce gap between the end of the toolbar and the last button
717 aTotalSize
.Width
+= gnGapSize
/2;
719 // Calculate the minimal size so that the window size of the tool bar
720 // can be adapted accordingly.
721 maMinimalSize
= aTotalSize
;
722 maMinimalSize
.Width
+= nTotalHorizontalGap
;
724 // Calculate the gaps between elements.
725 double nGapWidth (0);
728 if (aTotalSize
.Width
+ nTotalHorizontalGap
> aWindowBox
.Width
)
729 nTotalHorizontalGap
= aWindowBox
.Width
- aTotalSize
.Width
;
730 nGapWidth
= nTotalHorizontalGap
/ nGapCount
;
733 // Determine the location of the left edge.
737 case Left
: nX
= 0; break;
738 case Center
: nX
= (aWindowBox
.Width
- aTotalSize
.Width
- nTotalHorizontalGap
) / 2; break;
742 double nY ((aWindowBox
.Height
- aTotalSize
.Height
) / 2);
743 bIsHorizontal
= true;
745 /* push front or back ? ... */
746 /// check whether RTL interface or not
747 if(!AllSettings::GetLayoutRTL()){
749 for (const auto& rxPart
: maElementContainer
)
751 geometry::RealRectangle2D
aBoundingBox(
753 nX
+aPartSizes
[nIndex
].Width
, nY
+aTotalSize
.Height
);
755 // Add space for gaps between elements.
756 if (rxPart
->size() > 1 && bIsHorizontal
)
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
)
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
)
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
iBegin (rpPart
->begin());
883 for (iElement
=rpPart
->end()-1; iElement
!=iBegin
-1; --iElement
)
885 if (iElement
->get() == nullptr)
888 const awt::Size
aElementSize ((*iElement
)->GetBoundingSize(rxCanvas
));
891 if ((*iElement
)->IsFilling())
893 nY
= rBoundingBox
.Y1
;
894 (*iElement
)->SetSize(geometry::RealSize2D(aElementSize
.Width
, rBoundingBox
.Y2
- rBoundingBox
.Y1
));
897 nY
= rBoundingBox
.Y1
+ (rBoundingBox
.Y2
-rBoundingBox
.Y1
- aElementSize
.Height
) / 2;
898 (*iElement
)->SetLocation(awt::Point(sal_Int32(0.5 + nX
), sal_Int32(0.5 + nY
)));
899 nX
+= aElementSize
.Width
+ nGap
;
903 // reverse presentation time with current time
904 if (iElement
==iBegin
){
907 else if (iElement
==iBegin
+2){
910 const awt::Size
aNewElementSize ((*iElement
)->GetBoundingSize(rxCanvas
));
911 if ((*iElement
)->IsFilling())
913 nX
= rBoundingBox
.X1
;
914 (*iElement
)->SetSize(geometry::RealSize2D(rBoundingBox
.X2
- rBoundingBox
.X1
, aNewElementSize
.Height
));
917 nX
= rBoundingBox
.X1
+ (rBoundingBox
.X2
-rBoundingBox
.X1
- aNewElementSize
.Width
) / 2;
918 (*iElement
)->SetLocation(awt::Point(sal_Int32(0.5 + nX
), sal_Int32(0.5 + nY
)));
919 nY
+= aNewElementSize
.Height
+ nGap
;
921 // return the index as it was before the reversing
922 if (iElement
==iBegin
)
924 else if (iElement
==iBegin
+2)
931 void PresenterToolBar::Paint (
932 const awt::Rectangle
& rUpdateBox
,
933 const rendering::ViewState
& rViewState
)
935 OSL_ASSERT(mxCanvas
.is());
937 for (const auto& rxPart
: maElementContainer
)
939 for (auto& rxElement
: *rxPart
)
943 if ( ! rxElement
->IsOutside(rUpdateBox
))
944 rxElement
->Paint(mxCanvas
, rViewState
);
950 void PresenterToolBar::UpdateSlideNumber()
952 if( mxSlideShowController
.is() )
954 for (const auto& rxPart
: maElementContainer
)
956 for (auto& rxElement
: *rxPart
)
959 rxElement
->CurrentSlideHasChanged();
965 void PresenterToolBar::CheckMouseOver (
966 const css::awt::MouseEvent
& rEvent
,
967 const bool bOverWindow
,
968 const bool bMouseDown
)
970 css::awt::MouseEvent rTemp
=rEvent
;
971 if(AllSettings::GetLayoutRTL()){
972 awt::Rectangle aWindowBox
= mxWindow
->getPosSize();
973 rTemp
.X
=aWindowBox
.Width
-rTemp
.X
;
975 for (const auto& rxPart
: maElementContainer
)
977 for (auto& rxElement
: *rxPart
)
982 awt::Rectangle
aBox (rxElement
->GetBoundingBox());
983 const bool bIsOver
= bOverWindow
985 && aBox
.Width
+aBox
.X
-1 >= rTemp
.X
987 && aBox
.Height
+aBox
.Y
-1 >= rTemp
.Y
;
990 bIsOver
&& rTemp
.Buttons
!=0 && bMouseDown
&& rTemp
.ClickCount
>0);
995 void PresenterToolBar::ThrowIfDisposed() const
997 if (rBHelper
.bDisposed
|| rBHelper
.bInDispose
)
999 throw lang::DisposedException (
1000 "PresenterToolBar has already been disposed",
1001 const_cast<uno::XWeak
*>(static_cast<const uno::XWeak
*>(this)));
1005 //===== PresenterToolBarView ==================================================
1007 PresenterToolBarView::PresenterToolBarView (
1008 const Reference
<XComponentContext
>& rxContext
,
1009 const Reference
<XResourceId
>& rxViewId
,
1010 const rtl::Reference
<::sd::DrawController
>& rxController
,
1011 const ::rtl::Reference
<PresenterController
>& rpPresenterController
)
1012 : PresenterToolBarViewInterfaceBase(m_aMutex
),
1014 mpPresenterController(rpPresenterController
)
1018 Reference
<XConfigurationController
> xCC(rxController
->getConfigurationController(),UNO_SET_THROW
);
1019 mxPane
.set(xCC
->getResource(rxViewId
->getAnchor()), UNO_QUERY_THROW
);
1021 mxWindow
= mxPane
->getWindow();
1022 mxCanvas
= mxPane
->getCanvas();
1024 mpToolBar
= new PresenterToolBar(
1028 rpPresenterController
,
1029 PresenterToolBar::Center
);
1030 mpToolBar
->Initialize("PresenterScreenSettings/ToolBars/ToolBar");
1034 mxWindow
->addPaintListener(this);
1036 Reference
<awt::XWindowPeer
> xPeer (mxWindow
, UNO_QUERY
);
1038 xPeer
->setBackground(util::Color(0xff000000));
1040 mxWindow
->setVisible(true);
1043 catch (RuntimeException
&)
1050 PresenterToolBarView::~PresenterToolBarView()
1054 void SAL_CALL
PresenterToolBarView::disposing()
1056 Reference
<lang::XComponent
> xComponent
= mpToolBar
;
1057 mpToolBar
= nullptr;
1058 if (xComponent
.is())
1059 xComponent
->dispose();
1063 mxWindow
->removePaintListener(this);
1069 mpPresenterController
= nullptr;
1072 const ::rtl::Reference
<PresenterToolBar
>& PresenterToolBarView::GetPresenterToolBar() const
1077 //----- XPaintListener --------------------------------------------------------
1079 void SAL_CALL
PresenterToolBarView::windowPaint (const css::awt::PaintEvent
& rEvent
)
1081 awt::Rectangle
aWindowBox (mxWindow
->getPosSize());
1082 mpPresenterController
->GetCanvasHelper()->Paint(
1083 mpPresenterController
->GetViewBackground(mxViewId
->getResourceURL()),
1086 awt::Rectangle(0,0,aWindowBox
.Width
, aWindowBox
.Height
),
1090 //----- lang::XEventListener -------------------------------------------------
1092 void SAL_CALL
PresenterToolBarView::disposing (const lang::EventObject
& rEventObject
)
1094 if (rEventObject
.Source
== mxWindow
)
1098 //----- XResourceId -----------------------------------------------------------
1100 Reference
<XResourceId
> SAL_CALL
PresenterToolBarView::getResourceId()
1105 sal_Bool SAL_CALL
PresenterToolBarView::isAnchorOnly()
1110 //----- XDrawView -------------------------------------------------------------
1112 void SAL_CALL
PresenterToolBarView::setCurrentPage (const Reference
<drawing::XDrawPage
>& rxSlide
)
1114 Reference
<drawing::XDrawView
> xToolBar
= mpToolBar
;
1116 xToolBar
->setCurrentPage(rxSlide
);
1119 Reference
<drawing::XDrawPage
> SAL_CALL
PresenterToolBarView::getCurrentPage()
1124 //===== PresenterToolBar::Element =============================================
1129 ::rtl::Reference
<PresenterToolBar
> pToolBar
)
1130 : ElementInterfaceBase(m_aMutex
),
1131 mpToolBar(std::move(pToolBar
)),
1134 mbIsSelected(false),
1139 OSL_ASSERT(mpToolBar
->GetPresenterController().is());
1140 OSL_ASSERT(mpToolBar
->GetPresenterController()->GetWindowManager().is());
1144 void Element::SetModes (
1145 const SharedElementMode
& rpNormalMode
,
1146 const SharedElementMode
& rpMouseOverMode
,
1147 const SharedElementMode
& rpSelectedMode
,
1148 const SharedElementMode
& rpDisabledMode
,
1149 const SharedElementMode
& rpMouseOverSelectedMode
)
1151 mpNormal
= rpNormalMode
;
1152 mpMouseOver
= rpMouseOverMode
;
1153 mpSelected
= rpSelectedMode
;
1154 mpDisabled
= rpDisabledMode
;
1155 mpMouseOverSelected
= rpMouseOverSelectedMode
;
1156 mpMode
= rpNormalMode
;
1159 void Element::disposing()
1163 awt::Size
const & Element::GetBoundingSize (
1164 const Reference
<rendering::XCanvas
>& rxCanvas
)
1166 maSize
= CreateBoundingSize(rxCanvas
);
1170 awt::Rectangle
Element::GetBoundingBox() const
1172 return awt::Rectangle(maLocation
.X
,maLocation
.Y
, maSize
.Width
, maSize
.Height
);
1175 void Element::CurrentSlideHasChanged()
1180 void Element::SetLocation (const awt::Point
& rLocation
)
1182 maLocation
= rLocation
;
1185 void Element::SetSize (const geometry::RealSize2D
& rSize
)
1187 maSize
= awt::Size(sal_Int32(0.5+rSize
.Width
), sal_Int32(0.5+rSize
.Height
));
1190 bool Element::SetState (
1192 const bool bIsPressed
)
1194 bool bModified (mbIsOver
!= bIsOver
|| mbIsPressed
!= bIsPressed
);
1195 bool bClicked (mbIsPressed
&& bIsOver
&& ! bIsPressed
);
1198 mbIsPressed
= bIsPressed
;
1200 // When the element is disabled then ignore mouse over or selection.
1201 // When the element is selected then ignore mouse over.
1203 mpMode
= mpDisabled
;
1204 else if (mbIsSelected
&& mbIsOver
)
1205 mpMode
= mpMouseOverSelected
;
1206 else if (mbIsSelected
)
1207 mpMode
= mpSelected
;
1209 mpMode
= mpMouseOver
;
1213 if (bClicked
&& mbIsEnabled
)
1219 if (mpMode
->msAction
.isEmpty())
1225 if (!mpToolBar
->GetPresenterController())
1228 mpToolBar
->GetPresenterController()->DispatchUnoCommand(mpMode
->msAction
);
1229 mpToolBar
->RequestLayout();
1243 void Element::Invalidate (const bool bSynchronous
)
1245 OSL_ASSERT(mpToolBar
.is());
1246 mpToolBar
->InvalidateArea(GetBoundingBox(), bSynchronous
);
1249 bool Element::IsOutside (const awt::Rectangle
& rBox
)
1251 if (rBox
.X
>= maLocation
.X
+maSize
.Width
)
1253 else if (rBox
.Y
>= maLocation
.Y
+maSize
.Height
)
1255 else if (maLocation
.X
>= rBox
.X
+rBox
.Width
)
1257 else if (maLocation
.Y
>= rBox
.Y
+rBox
.Height
)
1264 bool Element::IsFilling() const
1269 void Element::UpdateState()
1271 OSL_ASSERT(mpToolBar
);
1272 OSL_ASSERT(mpToolBar
->GetPresenterController());
1277 util::URL
aURL (mpToolBar
->GetPresenterController()->CreateURLFromString(mpMode
->msAction
));
1278 Reference
<frame::XDispatch
> xDispatch (mpToolBar
->GetPresenterController()->GetDispatch(aURL
));
1281 xDispatch
->addStatusListener(this, aURL
);
1282 xDispatch
->removeStatusListener(this, aURL
);
1286 //----- lang::XEventListener --------------------------------------------------
1288 void SAL_CALL
Element::disposing (const css::lang::EventObject
&) {}
1290 //----- document::XEventListener ----------------------------------------------
1292 void SAL_CALL
Element::notifyEvent (const css::document::EventObject
&)
1297 //----- frame::XStatusListener ------------------------------------------------
1299 void SAL_CALL
Element::statusChanged (const css::frame::FeatureStateEvent
& rEvent
)
1301 bool bIsSelected (mbIsSelected
);
1302 bool bIsEnabled (rEvent
.IsEnabled
);
1303 rEvent
.State
>>= bIsSelected
;
1305 if (bIsSelected
!= mbIsSelected
|| bIsEnabled
!= mbIsEnabled
)
1307 mbIsEnabled
= bIsEnabled
;
1308 mbIsSelected
= bIsSelected
;
1309 SetState(mbIsOver
, mbIsPressed
);
1310 mpToolBar
->RequestLayout();
1314 } // end of anonymous namespace
1316 //===== ElementMode ===========================================================
1320 ElementMode::ElementMode()
1324 void ElementMode::ReadElementMode (
1325 const Reference
<beans::XPropertySet
>& rxElementProperties
,
1326 const OUString
& rsModeName
,
1327 std::shared_ptr
<ElementMode
> const & rpDefaultMode
,
1328 ::sdext::presenter::PresenterToolBar::Context
const & rContext
)
1332 Reference
<container::XHierarchicalNameAccess
> xNode (
1333 PresenterConfigurationAccess::GetProperty(rxElementProperties
, rsModeName
),
1335 Reference
<beans::XPropertySet
> xProperties (
1336 PresenterConfigurationAccess::GetNodeProperties(xNode
, OUString()));
1337 if (!xProperties
.is() && rpDefaultMode
!= nullptr)
1339 // The mode is not specified. Use the given, possibly empty,
1340 // default mode instead.
1341 mpIcon
= rpDefaultMode
->mpIcon
;
1342 msAction
= rpDefaultMode
->msAction
;
1343 maText
= rpDefaultMode
->maText
;
1347 if ( ! (PresenterConfigurationAccess::GetProperty(xProperties
, "Action") >>= msAction
))
1348 if (rpDefaultMode
!= nullptr)
1349 msAction
= rpDefaultMode
->msAction
;
1351 // Read text and font
1352 OUString
sText(rpDefaultMode
!= nullptr ? rpDefaultMode
->maText
.GetText() : OUString());
1353 PresenterConfigurationAccess::GetProperty(xProperties
, "Text") >>= sText
;
1354 Reference
<container::XHierarchicalNameAccess
> xFontNode (
1355 PresenterConfigurationAccess::GetProperty(xProperties
, "Font"), UNO_QUERY
);
1356 PresenterTheme::SharedFontDescriptor
pFont(PresenterTheme::ReadFont(
1357 xFontNode
, rpDefaultMode
!= nullptr ? rpDefaultMode
->maText
.GetFont()
1358 : PresenterTheme::SharedFontDescriptor()));
1359 maText
= Text(sText
,pFont
);
1361 // Read bitmaps to display as icons.
1362 Reference
<container::XHierarchicalNameAccess
> xIconNode (
1363 PresenterConfigurationAccess::GetProperty(xProperties
, "Icon"), UNO_QUERY
);
1364 mpIcon
= PresenterBitmapContainer::LoadBitmap(
1365 xIconNode
, "", rContext
.mxPresenterHelper
, rContext
.mxCanvas
,
1366 rpDefaultMode
!= nullptr ? rpDefaultMode
->mpIcon
: SharedBitmapDescriptor());
1374 } // end of anonymous namespace
1376 //===== Button ================================================================
1380 ::rtl::Reference
<Element
> Button::Create (
1381 const ::rtl::Reference
<PresenterToolBar
>& rpToolBar
)
1383 ::rtl::Reference
<Button
> pElement (new Button(rpToolBar
));
1384 pElement
->Initialize();
1389 const ::rtl::Reference
<PresenterToolBar
>& rpToolBar
)
1390 : Element(rpToolBar
),
1391 mbIsListenerRegistered(false)
1393 OSL_ASSERT(mpToolBar
);
1394 OSL_ASSERT(mpToolBar
->GetPresenterController().is());
1395 OSL_ASSERT(mpToolBar
->GetPresenterController()->GetWindowManager().is());
1398 void Button::Initialize()
1400 mpToolBar
->GetPresenterController()->GetWindowManager()->AddLayoutListener(this);
1401 mbIsListenerRegistered
= true;
1404 void Button::disposing()
1406 OSL_ASSERT(mpToolBar
);
1407 if (mpToolBar
&& mbIsListenerRegistered
)
1409 OSL_ASSERT(mpToolBar
->GetPresenterController().is());
1410 OSL_ASSERT(mpToolBar
->GetPresenterController()->GetWindowManager().is());
1412 mbIsListenerRegistered
= false;
1413 mpToolBar
->GetPresenterController()->GetWindowManager()->RemoveLayoutListener(this);
1415 Element::disposing();
1418 void Button::Paint (
1419 const Reference
<rendering::XCanvas
>& rxCanvas
,
1420 const rendering::ViewState
& rViewState
)
1422 OSL_ASSERT(rxCanvas
.is());
1427 if (!mpMode
->mpIcon
)
1430 geometry::RealRectangle2D
aTextBBox (mpMode
->maText
.GetBoundingBox(rxCanvas
));
1431 sal_Int32
nTextHeight (sal::static_int_cast
<sal_Int32
>(0.5 + aTextBBox
.Y2
- aTextBBox
.Y1
));
1433 PaintIcon(rxCanvas
, nTextHeight
, rViewState
);
1434 mpMode
->maText
.Paint(rxCanvas
, rViewState
, GetBoundingBox());
1437 awt::Size
Button::CreateBoundingSize (
1438 const Reference
<rendering::XCanvas
>& rxCanvas
)
1443 geometry::RealRectangle2D
aTextBBox (mpMode
->maText
.GetBoundingBox(rxCanvas
));
1445 // tdf#128964 This ensures that if the text of a button changes due to a change in
1446 // the state of the button the other buttons of the toolbar do not move. The button is
1447 // allotted the maximum size so that it doesn't resize during a change of state.
1448 geometry::RealRectangle2D
aTextBBoxNormal (mpNormal
->maText
.GetBoundingBox(rxCanvas
));
1449 geometry::RealRectangle2D
aTextBBoxMouseOver (mpMouseOver
->maText
.GetBoundingBox(rxCanvas
));
1450 geometry::RealRectangle2D
aTextBBoxSelected (mpSelected
->maText
.GetBoundingBox(rxCanvas
));
1451 geometry::RealRectangle2D
aTextBBoxDisabled (mpDisabled
->maText
.GetBoundingBox(rxCanvas
));
1452 geometry::RealRectangle2D
aTextBBoxMouseOverSelected (mpMouseOverSelected
->maText
.GetBoundingBox(rxCanvas
));
1453 std::vector
<sal_Int32
> widths
1455 sal::static_int_cast
<sal_Int32
>(0.5 + aTextBBoxNormal
.X2
- aTextBBoxNormal
.X1
),
1456 sal::static_int_cast
<sal_Int32
>(0.5 + aTextBBoxMouseOver
.X2
- aTextBBoxMouseOver
.X1
),
1457 sal::static_int_cast
<sal_Int32
>(0.5 + aTextBBoxSelected
.X2
- aTextBBoxSelected
.X1
),
1458 sal::static_int_cast
<sal_Int32
>(0.5 + aTextBBoxDisabled
.X2
- aTextBBoxDisabled
.X1
),
1459 sal::static_int_cast
<sal_Int32
>(0.5 + aTextBBoxMouseOverSelected
.X2
- aTextBBoxMouseOverSelected
.X1
)
1462 sal_Int32
nTextHeight (sal::static_int_cast
<sal_Int32
>(0.5 + aTextBBox
.Y2
- aTextBBox
.Y1
));
1463 Reference
<rendering::XBitmap
> xBitmap
;
1465 xBitmap
= mpMode
->mpIcon
->GetNormalBitmap();
1468 const sal_Int32
nGap (5);
1469 geometry::IntegerSize2D
aSize (xBitmap
->getSize());
1471 ::std::max(aSize
.Width
, *std::max_element(widths
.begin(), widths
.end())),
1472 aSize
.Height
+ nGap
+ nTextHeight
);
1476 return awt::Size(*std::max_element(widths
.begin(), widths
.end()), nTextHeight
);
1480 void Button::PaintIcon (
1481 const Reference
<rendering::XCanvas
>& rxCanvas
,
1482 const sal_Int32 nTextHeight
,
1483 const rendering::ViewState
& rViewState
)
1488 Reference
<rendering::XBitmap
> xBitmap (mpMode
->mpIcon
->GetBitmap(GetMode()));
1492 /// check whether RTL interface or not
1493 if(!AllSettings::GetLayoutRTL()){
1494 const sal_Int32
nX (maLocation
.X
1495 + (maSize
.Width
-xBitmap
->getSize().Width
) / 2);
1496 const sal_Int32
nY (maLocation
.Y
1497 + (maSize
.Height
- nTextHeight
- xBitmap
->getSize().Height
) / 2);
1498 const rendering::RenderState
aRenderState(
1499 geometry::AffineMatrix2D(1,0,nX
, 0,1,nY
),
1501 Sequence
<double>(4),
1502 rendering::CompositeOperation::OVER
);
1503 rxCanvas
->drawBitmap(xBitmap
, rViewState
, aRenderState
);
1506 const sal_Int32
nX (maLocation
.X
1507 + (maSize
.Width
+xBitmap
->getSize().Width
) / 2);
1508 const sal_Int32
nY (maLocation
.Y
1509 + (maSize
.Height
- nTextHeight
- xBitmap
->getSize().Height
) / 2);
1510 const rendering::RenderState
aRenderState(
1511 geometry::AffineMatrix2D(-1,0,nX
, 0,1,nY
),
1513 Sequence
<double>(4),
1514 rendering::CompositeOperation::OVER
);
1515 rxCanvas
->drawBitmap(xBitmap
, rViewState
, aRenderState
);
1519 PresenterBitmapDescriptor::Mode
Button::GetMode() const
1522 return PresenterBitmapDescriptor::Disabled
;
1523 else if (mbIsPressed
)
1524 return PresenterBitmapDescriptor::ButtonDown
;
1526 return PresenterBitmapDescriptor::MouseOver
;
1528 return PresenterBitmapDescriptor::Normal
;
1531 //----- lang::XEventListener --------------------------------------------------
1533 void SAL_CALL
Button::disposing (const css::lang::EventObject
& rEvent
)
1535 mbIsListenerRegistered
= false;
1536 Element::disposing(rEvent
);
1539 } // end of anonymous namespace
1541 //===== PresenterToolBar::Label ===============================================
1545 Label::Label (const ::rtl::Reference
<PresenterToolBar
>& rpToolBar
)
1546 : Element(rpToolBar
)
1550 awt::Size
Label::CreateBoundingSize (
1551 const Reference
<rendering::XCanvas
>& rxCanvas
)
1554 return awt::Size(0,0);
1556 geometry::RealRectangle2D
aTextBBox (mpMode
->maText
.GetBoundingBox(rxCanvas
));
1558 sal::static_int_cast
<sal_Int32
>(0.5 + aTextBBox
.X2
- aTextBBox
.X1
),
1559 sal::static_int_cast
<sal_Int32
>(0.5 + aTextBBox
.Y2
- aTextBBox
.Y1
));
1562 void Label::SetText (const OUString
& rsText
)
1564 OSL_ASSERT(mpToolBar
);
1568 const bool bRequestLayout (mpMode
->maText
.GetText().getLength() != rsText
.getLength());
1570 mpMode
->maText
.SetText(rsText
);
1571 // Just use the character count for determining whether a layout is
1572 // necessary. This is an optimization to avoid layouts every time a new
1573 // time value is set on some labels.
1575 mpToolBar
->RequestLayout();
1581 const Reference
<rendering::XCanvas
>& rxCanvas
,
1582 const rendering::ViewState
& rViewState
)
1584 OSL_ASSERT(rxCanvas
.is());
1588 mpMode
->maText
.Paint(rxCanvas
, rViewState
, GetBoundingBox());
1591 bool Label::SetState (const bool, const bool)
1593 // For labels there is no mouse over effect.
1594 return Element::SetState(false, false);
1597 } // end of anonymous namespace
1599 //===== Text ==================================================================
1609 PresenterTheme::SharedFontDescriptor pFont
)
1610 : msText(std::move(sText
)),
1611 mpFont(std::move(pFont
))
1615 void Text::SetText (const OUString
& rsText
)
1620 const OUString
& Text::GetText() const
1625 const PresenterTheme::SharedFontDescriptor
& Text::GetFont() const
1631 const Reference
<rendering::XCanvas
>& rxCanvas
,
1632 const rendering::ViewState
& rViewState
,
1633 const awt::Rectangle
& rBoundingBox
)
1635 OSL_ASSERT(rxCanvas
.is());
1637 if (msText
.isEmpty())
1642 if ( ! mpFont
->mxFont
.is())
1643 mpFont
->PrepareFont(rxCanvas
);
1644 if ( ! mpFont
->mxFont
.is())
1647 rendering::StringContext
aContext (msText
, 0, msText
.getLength());
1649 Reference
<rendering::XTextLayout
> xLayout (
1650 mpFont
->mxFont
->createTextLayout(
1652 rendering::TextDirection::WEAK_LEFT_TO_RIGHT
,
1654 geometry::RealRectangle2D
aBox (xLayout
->queryTextBounds());
1655 const double nTextWidth
= aBox
.X2
- aBox
.X1
;
1656 const double nY
= rBoundingBox
.Y
+ rBoundingBox
.Height
- aBox
.Y2
;
1657 const double nX
= rBoundingBox
.X
+ (rBoundingBox
.Width
- nTextWidth
)/2;
1659 rendering::RenderState
aRenderState(
1660 geometry::AffineMatrix2D(1,0,nX
, 0,1,nY
),
1662 Sequence
<double>(4),
1663 rendering::CompositeOperation::SOURCE
);
1664 PresenterCanvasHelper::SetDeviceColor(aRenderState
, mpFont
->mnColor
);
1665 rxCanvas
->drawTextLayout(
1671 geometry::RealRectangle2D
Text::GetBoundingBox (const Reference
<rendering::XCanvas
>& rxCanvas
)
1673 if (mpFont
&& !msText
.isEmpty())
1675 if ( ! mpFont
->mxFont
.is())
1676 mpFont
->PrepareFont(rxCanvas
);
1677 if (mpFont
->mxFont
.is())
1679 rendering::StringContext
aContext (msText
, 0, msText
.getLength());
1680 Reference
<rendering::XTextLayout
> xLayout (
1681 mpFont
->mxFont
->createTextLayout(
1683 rendering::TextDirection::WEAK_LEFT_TO_RIGHT
,
1685 return xLayout
->queryTextBounds();
1688 return geometry::RealRectangle2D(0,0,0,0);
1691 //===== TimeFormatter =========================================================
1693 OUString
TimeFormatter::FormatTime (const oslDateTime
& rTime
)
1695 OUStringBuffer sText
;
1697 const sal_Int32
nHours (sal::static_int_cast
<sal_Int32
>(rTime
.Hours
));
1698 const sal_Int32
nMinutes (sal::static_int_cast
<sal_Int32
>(rTime
.Minutes
));
1699 const sal_Int32
nSeconds(sal::static_int_cast
<sal_Int32
>(rTime
.Seconds
));
1701 sText
.append(OUString::number(nHours
) + ":");
1704 const OUString
sMinutes (OUString::number(nMinutes
));
1705 if (sMinutes
.getLength() == 1)
1707 sText
.append(sMinutes
);
1711 const OUString
sSeconds (OUString::number(nSeconds
));
1712 if (sSeconds
.getLength() == 1)
1714 sText
.append(sSeconds
);
1715 return sText
.makeStringAndClear();
1718 //===== TimeLabel =============================================================
1720 TimeLabel::TimeLabel (const ::rtl::Reference
<PresenterToolBar
>& rpToolBar
)
1725 void SAL_CALL
TimeLabel::disposing()
1727 PresenterClockTimer::Instance(mpToolBar
->GetComponentContext())->RemoveListener(mpListener
);
1731 void TimeLabel::ConnectToTimer()
1733 mpListener
= std::make_shared
<Listener
>(this);
1734 PresenterClockTimer::Instance(mpToolBar
->GetComponentContext())->AddListener(mpListener
);
1737 //===== CurrentTimeLabel ======================================================
1739 ::rtl::Reference
<Element
> CurrentTimeLabel::Create (
1740 const ::rtl::Reference
<PresenterToolBar
>& rpToolBar
)
1742 ::rtl::Reference
<TimeLabel
> pElement(new CurrentTimeLabel(rpToolBar
));
1743 pElement
->ConnectToTimer();
1747 CurrentTimeLabel::~CurrentTimeLabel()
1751 CurrentTimeLabel::CurrentTimeLabel (
1752 const ::rtl::Reference
<PresenterToolBar
>& rpToolBar
)
1753 : TimeLabel(rpToolBar
)
1757 void CurrentTimeLabel::TimeHasChanged (const oslDateTime
& rCurrentTime
)
1759 SetText(TimeFormatter::FormatTime(rCurrentTime
));
1763 void CurrentTimeLabel::SetModes (
1764 const SharedElementMode
& rpNormalMode
,
1765 const SharedElementMode
& rpMouseOverMode
,
1766 const SharedElementMode
& rpSelectedMode
,
1767 const SharedElementMode
& rpDisabledMode
,
1768 const SharedElementMode
& rpMouseOverSelectedMode
)
1770 TimeLabel::SetModes(rpNormalMode
, rpMouseOverMode
, rpSelectedMode
, rpDisabledMode
, rpMouseOverSelectedMode
);
1771 SetText(TimeFormatter::FormatTime(PresenterClockTimer::GetCurrentTime()));
1774 //===== PresentationTimeLabel =================================================
1776 ::rtl::Reference
<Element
> PresentationTimeLabel::Create (
1777 const ::rtl::Reference
<PresenterToolBar
>& rpToolBar
)
1779 ::rtl::Reference
<TimeLabel
> pElement(new PresentationTimeLabel(rpToolBar
));
1780 pElement
->ConnectToTimer();
1784 PresentationTimeLabel::~PresentationTimeLabel()
1786 mpToolBar
->GetPresenterController()->SetPresentationTime(nullptr);
1789 PresentationTimeLabel::PresentationTimeLabel (
1790 const ::rtl::Reference
<PresenterToolBar
>& rpToolBar
)
1791 : TimeLabel(rpToolBar
),
1795 setPauseStatus(false);
1796 TimeValue
pauseTime(0,0);
1797 setPauseTimeValue(pauseTime
);
1798 mpToolBar
->GetPresenterController()->SetPresentationTime(this);
1801 void PresentationTimeLabel::restart()
1803 TimeValue
pauseTime(0, 0);
1804 setPauseTimeValue(pauseTime
);
1805 maStartTimeValue
.Seconds
= 0;
1806 maStartTimeValue
.Nanosec
= 0;
1809 bool PresentationTimeLabel::isPaused()
1814 void PresentationTimeLabel::setPauseStatus(const bool pauseStatus
)
1816 paused
= pauseStatus
;
1819 const TimeValue
& PresentationTimeLabel::getPauseTimeValue() const
1821 return pauseTimeValue
;
1824 void PresentationTimeLabel::setPauseTimeValue(const TimeValue pauseTime
)
1826 //store the time at which the presentation was paused
1827 pauseTimeValue
= pauseTime
;
1830 void PresentationTimeLabel::TimeHasChanged (const oslDateTime
& rCurrentTime
)
1832 TimeValue aCurrentTimeValue
;
1833 if (!osl_getTimeValueFromDateTime(&rCurrentTime
, &aCurrentTimeValue
))
1836 if (maStartTimeValue
.Seconds
==0 && maStartTimeValue
.Nanosec
==0)
1838 // This method is called for the first time. Initialize the
1839 // start time. The start time is rounded to nearest second to
1840 // keep the time updates synchronized with the current time label.
1841 maStartTimeValue
= aCurrentTimeValue
;
1842 if (maStartTimeValue
.Nanosec
>= 500000000)
1843 maStartTimeValue
.Seconds
+= 1;
1844 maStartTimeValue
.Nanosec
= 0;
1847 //The start time value is incremented by the amount of time
1848 //the presentation was paused for in order to continue the
1849 //timer from the same position
1852 TimeValue pauseTime
= getPauseTimeValue();
1853 if(pauseTime
.Seconds
!= 0 || pauseTime
.Nanosec
!= 0)
1855 TimeValue
incrementValue(0, 0);
1856 incrementValue
.Seconds
= aCurrentTimeValue
.Seconds
- pauseTime
.Seconds
;
1857 if(pauseTime
.Nanosec
> aCurrentTimeValue
.Nanosec
)
1859 incrementValue
.Nanosec
= 1000000000 + aCurrentTimeValue
.Nanosec
- pauseTime
.Nanosec
;
1863 incrementValue
.Nanosec
= aCurrentTimeValue
.Nanosec
- pauseTime
.Nanosec
;
1866 maStartTimeValue
.Seconds
+= incrementValue
.Seconds
;
1867 maStartTimeValue
.Nanosec
+= incrementValue
.Nanosec
;
1868 if(maStartTimeValue
.Nanosec
>= 1000000000)
1870 maStartTimeValue
.Seconds
+= 1;
1871 maStartTimeValue
.Nanosec
-= 1000000000;
1874 TimeValue
pauseTime_(0, 0);
1875 setPauseTimeValue(pauseTime_
);
1880 TimeValue pauseTime
= getPauseTimeValue();
1881 if(pauseTime
.Seconds
== 0 && pauseTime
.Nanosec
== 0)
1883 setPauseTimeValue(aCurrentTimeValue
);
1887 TimeValue aElapsedTimeValue
;
1888 aElapsedTimeValue
.Seconds
= aCurrentTimeValue
.Seconds
- maStartTimeValue
.Seconds
;
1889 aElapsedTimeValue
.Nanosec
= aCurrentTimeValue
.Nanosec
- maStartTimeValue
.Nanosec
;
1891 oslDateTime aElapsedDateTime
;
1892 if (osl_getDateTimeFromTimeValue(&aElapsedTimeValue
, &aElapsedDateTime
) && !isPaused())
1894 SetText(TimeFormatter::FormatTime(aElapsedDateTime
));
1899 void PresentationTimeLabel::SetModes (
1900 const SharedElementMode
& rpNormalMode
,
1901 const SharedElementMode
& rpMouseOverMode
,
1902 const SharedElementMode
& rpSelectedMode
,
1903 const SharedElementMode
& rpDisabledMode
,
1904 const SharedElementMode
& rpMouseOverSelectedMode
)
1906 TimeLabel::SetModes(rpNormalMode
, rpMouseOverMode
, rpSelectedMode
, rpDisabledMode
, rpMouseOverSelectedMode
);
1908 oslDateTime aStartDateTime
;
1909 if (osl_getDateTimeFromTimeValue(&maStartTimeValue
, &aStartDateTime
))
1911 SetText(TimeFormatter::FormatTime(aStartDateTime
));
1915 //===== VerticalSeparator =====================================================
1917 VerticalSeparator::VerticalSeparator (
1918 const ::rtl::Reference
<PresenterToolBar
>& rpToolBar
)
1919 : Element(rpToolBar
)
1923 void VerticalSeparator::Paint (
1924 const Reference
<rendering::XCanvas
>& rxCanvas
,
1925 const rendering::ViewState
& rViewState
)
1927 OSL_ASSERT(rxCanvas
.is());
1929 awt::Rectangle
aBBox (GetBoundingBox());
1931 rendering::RenderState
aRenderState(
1932 geometry::AffineMatrix2D(1,0,aBBox
.X
, 0,1,aBBox
.Y
),
1934 Sequence
<double>(4),
1935 rendering::CompositeOperation::OVER
);
1938 PresenterTheme::SharedFontDescriptor
pFont (mpMode
->maText
.GetFont());
1940 PresenterCanvasHelper::SetDeviceColor(aRenderState
, pFont
->mnColor
);
1943 Reference
<rendering::XBitmap
> xBitmap(mpToolBar
->GetPresenterController()->GetPresenterHelper()->loadBitmap("bitmaps/Separator.png", rxCanvas
));
1947 rxCanvas
->drawBitmap(
1953 awt::Size
VerticalSeparator::CreateBoundingSize (
1954 const Reference
<rendering::XCanvas
>&)
1956 return awt::Size(1,20);
1959 bool VerticalSeparator::IsFilling() const
1964 //===== HorizontalSeparator ===================================================
1966 HorizontalSeparator::HorizontalSeparator (
1967 const ::rtl::Reference
<PresenterToolBar
>& rpToolBar
)
1968 : Element(rpToolBar
)
1972 void HorizontalSeparator::Paint (
1973 const Reference
<rendering::XCanvas
>& rxCanvas
,
1974 const rendering::ViewState
& rViewState
)
1976 OSL_ASSERT(rxCanvas
.is());
1978 awt::Rectangle
aBBox (GetBoundingBox());
1980 rendering::RenderState
aRenderState(
1981 geometry::AffineMatrix2D(1,0,0, 0,1,0),
1983 Sequence
<double>(4),
1984 rendering::CompositeOperation::OVER
);
1987 PresenterTheme::SharedFontDescriptor
pFont (mpMode
->maText
.GetFont());
1989 PresenterCanvasHelper::SetDeviceColor(aRenderState
, pFont
->mnColor
);
1992 rxCanvas
->fillPolyPolygon(
1993 PresenterGeometryHelper::CreatePolygon(aBBox
, rxCanvas
->getDevice()),
1998 awt::Size
HorizontalSeparator::CreateBoundingSize (
1999 const Reference
<rendering::XCanvas
>&)
2001 return awt::Size(20,1);
2004 bool HorizontalSeparator::IsFilling() const
2009 } // end of anonymous namespace
2011 } // end of namespace ::sdext::presenter
2013 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */