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/settings.hxx>
21 #include "PresenterToolBar.hxx"
23 #include "PresenterBitmapContainer.hxx"
24 #include "PresenterCanvasHelper.hxx"
25 #include "PresenterGeometryHelper.hxx"
26 #include "PresenterPaintManager.hxx"
27 #include "PresenterTimer.hxx"
28 #include "PresenterWindowManager.hxx"
30 #include <cppuhelper/compbase.hxx>
31 #include <com/sun/star/awt/XWindowPeer.hpp>
32 #include <com/sun/star/drawing/framework/XControllerManager.hpp>
33 #include <com/sun/star/drawing/framework/XConfigurationController.hpp>
34 #include <com/sun/star/drawing/framework/XPane.hpp>
35 #include <com/sun/star/geometry/AffineMatrix2D.hpp>
36 #include <com/sun/star/rendering/CompositeOperation.hpp>
37 #include <com/sun/star/rendering/RenderState.hpp>
38 #include <com/sun/star/rendering/TextDirection.hpp>
39 #include <com/sun/star/rendering/ViewState.hpp>
40 #include <com/sun/star/rendering/XSpriteCanvas.hpp>
41 #include <com/sun/star/util/Color.hpp>
42 #include <rtl/ustrbuf.hxx>
44 using namespace ::com::sun::star
;
45 using namespace ::com::sun::star::uno
;
46 using namespace ::com::sun::star::drawing::framework
;
48 namespace sdext::presenter
{
50 const sal_Int32
gnGapSize (20);
59 const OUString
& rsText
,
60 const PresenterTheme::SharedFontDescriptor
& rpFont
);
62 void SetText (const OUString
& rsText
);
63 const OUString
& GetText() const;
64 const PresenterTheme::SharedFontDescriptor
& GetFont() const;
67 const Reference
<rendering::XCanvas
>& rxCanvas
,
68 const rendering::ViewState
& rViewState
,
69 const awt::Rectangle
& rBoundingBox
);
71 geometry::RealRectangle2D
GetBoundingBox (
72 const Reference
<rendering::XCanvas
>& rxCanvas
);
76 PresenterTheme::SharedFontDescriptor mpFont
;
83 ElementMode(const ElementMode
&) = delete;
84 ElementMode
& operator=(const ElementMode
&) = delete;
86 SharedBitmapDescriptor mpIcon
;
90 void ReadElementMode (
91 const Reference
<beans::XPropertySet
>& rxProperties
,
92 const OUString
& rsModeName
,
93 std::shared_ptr
<ElementMode
> const & rpDefaultMode
,
94 ::sdext::presenter::PresenterToolBar::Context
const & rContext
);
96 typedef std::shared_ptr
<ElementMode
> SharedElementMode
;
98 } // end of anonymous namespace
100 class PresenterToolBar::Context
104 Context(const Context
&) = delete;
105 Context
& operator=(const Context
&) = delete;
106 Reference
<drawing::XPresenterHelper
> mxPresenterHelper
;
107 css::uno::Reference
<css::rendering::XCanvas
> mxCanvas
;
110 //===== PresenterToolBar::Element =============================================
113 typedef cppu::WeakComponentImplHelper
<
114 css::document::XEventListener
,
115 css::frame::XStatusListener
116 > ElementInterfaceBase
;
119 : private ::cppu::BaseMutex
,
120 public ElementInterfaceBase
123 explicit Element (const ::rtl::Reference
<PresenterToolBar
>& rpToolBar
);
124 Element(const Element
&) = delete;
125 Element
& operator=(const Element
&) = delete;
127 virtual void SAL_CALL
disposing() override
;
129 virtual void SetModes (
130 const SharedElementMode
& rpNormalMode
,
131 const SharedElementMode
& rpMouseOverMode
,
132 const SharedElementMode
& rpSelectedMode
,
133 const SharedElementMode
& rpDisabledMode
,
134 const SharedElementMode
& rpMouseOverSelectedMode
);
135 void CurrentSlideHasChanged();
136 void SetLocation (const awt::Point
& rLocation
);
137 void SetSize (const geometry::RealSize2D
& rSize
);
139 const Reference
<rendering::XCanvas
>& rxCanvas
,
140 const rendering::ViewState
& rViewState
) = 0;
141 awt::Size
const & GetBoundingSize (
142 const Reference
<rendering::XCanvas
>& rxCanvas
);
143 awt::Rectangle
GetBoundingBox() const;
144 virtual bool SetState (const bool bIsOver
, const bool bIsPressed
);
145 void Invalidate (const bool bSynchronous
);
146 bool IsOutside (const awt::Rectangle
& rBox
);
147 virtual bool IsFilling() const;
150 // lang::XEventListener
152 virtual void SAL_CALL
disposing (const css::lang::EventObject
& rEvent
) override
;
154 // document::XEventListener
156 virtual void SAL_CALL
notifyEvent (const css::document::EventObject
& rEvent
) override
;
158 // frame::XStatusListener
160 virtual void SAL_CALL
statusChanged (const css::frame::FeatureStateEvent
& rEvent
) override
;
163 ::rtl::Reference
<PresenterToolBar
> mpToolBar
;
164 awt::Point maLocation
;
166 SharedElementMode mpNormal
;
167 SharedElementMode mpMouseOver
;
168 SharedElementMode mpSelected
;
169 SharedElementMode mpDisabled
;
170 SharedElementMode mpMouseOverSelected
;
171 SharedElementMode mpMode
;
176 virtual awt::Size
CreateBoundingSize (
177 const Reference
<rendering::XCanvas
>& rxCanvas
) = 0;
179 bool IsEnabled() const { return mbIsEnabled
;}
184 } // end of anonymous namespace
186 class PresenterToolBar::ElementContainerPart
187 : public ::std::vector
<rtl::Reference
<Element
> >
191 //===== Button ================================================================
195 class Button
: public Element
198 static ::rtl::Reference
<Element
> Create (
199 const ::rtl::Reference
<PresenterToolBar
>& rpToolBar
);
201 virtual void SAL_CALL
disposing() override
;
204 const Reference
<rendering::XCanvas
>& rxCanvas
,
205 const rendering::ViewState
& rViewState
) override
;
207 // lang::XEventListener
209 virtual void SAL_CALL
disposing (const css::lang::EventObject
& rEvent
) override
;
212 virtual awt::Size
CreateBoundingSize (
213 const Reference
<rendering::XCanvas
>& rxCanvas
) override
;
216 bool mbIsListenerRegistered
;
218 Button (const ::rtl::Reference
<PresenterToolBar
>& rpToolBar
);
221 const Reference
<rendering::XCanvas
>& rxCanvas
,
222 const sal_Int32 nTextHeight
,
223 const rendering::ViewState
& rViewState
);
224 PresenterBitmapDescriptor::Mode
GetMode() const;
227 //===== Label =================================================================
229 class Label
: public Element
232 explicit Label (const ::rtl::Reference
<PresenterToolBar
>& rpToolBar
);
234 void SetText (const OUString
& rsText
);
236 const Reference
<rendering::XCanvas
>& rxCanvas
,
237 const rendering::ViewState
& rViewState
) override
;
238 virtual bool SetState (const bool bIsOver
, const bool bIsPressed
) override
;
241 virtual awt::Size
CreateBoundingSize (
242 const Reference
<rendering::XCanvas
>& rxCanvas
) override
;
245 // Some specialized controls.
250 static OUString
FormatTime (const oslDateTime
& rTime
);
253 class TimeLabel
: public Label
256 void ConnectToTimer();
257 virtual void TimeHasChanged (const oslDateTime
& rCurrentTime
) = 0;
259 explicit TimeLabel(const ::rtl::Reference
<PresenterToolBar
>& rpToolBar
);
260 using Element::disposing
;
261 virtual void SAL_CALL
disposing() override
;
263 class Listener
: public PresenterClockTimer::Listener
266 explicit Listener (const ::rtl::Reference
<TimeLabel
>& rxLabel
)
267 : mxLabel(rxLabel
) {}
268 virtual ~Listener() {}
269 virtual void TimeHasChanged (const oslDateTime
& rCurrentTime
) override
270 { if (mxLabel
.is()) mxLabel
->TimeHasChanged(rCurrentTime
); }
272 ::rtl::Reference
<TimeLabel
> mxLabel
;
274 std::shared_ptr
<PresenterClockTimer::Listener
> mpListener
;
277 class CurrentTimeLabel
: public TimeLabel
280 static ::rtl::Reference
<Element
> Create (
281 const ::rtl::Reference
<PresenterToolBar
>& rpToolBar
);
282 virtual void SetModes (
283 const SharedElementMode
& rpNormalMode
,
284 const SharedElementMode
& rpMouseOverMode
,
285 const SharedElementMode
& rpSelectedMode
,
286 const SharedElementMode
& rpDisabledMode
,
287 const SharedElementMode
& rpMouseOverSelectedMode
) override
;
289 CurrentTimeLabel (const ::rtl::Reference
<PresenterToolBar
>& rpToolBar
);
290 virtual ~CurrentTimeLabel() override
;
291 virtual void TimeHasChanged (const oslDateTime
& rCurrentTime
) override
;
294 class PresentationTimeLabel
: public TimeLabel
, public IPresentationTime
297 static ::rtl::Reference
<Element
> Create (
298 const ::rtl::Reference
<PresenterToolBar
>& rpToolBar
);
299 virtual void SetModes (
300 const SharedElementMode
& rpNormalMode
,
301 const SharedElementMode
& rpMouseOverMode
,
302 const SharedElementMode
& rpSelectedMode
,
303 const SharedElementMode
& rpDisabledMode
,
304 const SharedElementMode
& rpMouseOverSelectedMode
) override
;
305 virtual void restart() override
;
306 virtual bool isPaused() override
;
307 virtual void setPauseStatus(const bool pauseStatus
) override
;
308 const TimeValue
& getPauseTimeValue() const;
309 void setPauseTimeValue(const TimeValue pauseTime
);
311 TimeValue maStartTimeValue
;
312 TimeValue pauseTimeValue
;
313 PresentationTimeLabel (const ::rtl::Reference
<PresenterToolBar
>& rpToolBar
);
315 virtual ~PresentationTimeLabel() override
;
316 virtual void TimeHasChanged (const oslDateTime
& rCurrentTime
) override
;
319 class VerticalSeparator
: public Element
322 explicit VerticalSeparator (const ::rtl::Reference
<PresenterToolBar
>& rpToolBar
);
324 const Reference
<rendering::XCanvas
>& rxCanvas
,
325 const rendering::ViewState
& rViewState
) override
;
326 virtual bool IsFilling() const override
;
329 virtual awt::Size
CreateBoundingSize (
330 const Reference
<rendering::XCanvas
>& rxCanvas
) override
;
333 class HorizontalSeparator
: public Element
336 explicit HorizontalSeparator (const ::rtl::Reference
<PresenterToolBar
>& rpToolBar
);
338 const Reference
<rendering::XCanvas
>& rxCanvas
,
339 const rendering::ViewState
& rViewState
) override
;
340 virtual bool IsFilling() const override
;
343 virtual awt::Size
CreateBoundingSize (
344 const Reference
<rendering::XCanvas
>& rxCanvas
) override
;
346 } // end of anonymous namespace
348 //===== PresenterToolBar ======================================================
350 PresenterToolBar::PresenterToolBar (
351 const Reference
<XComponentContext
>& rxContext
,
352 const css::uno::Reference
<css::awt::XWindow
>& rxWindow
,
353 const css::uno::Reference
<css::rendering::XCanvas
>& rxCanvas
,
354 const ::rtl::Reference
<PresenterController
>& rpPresenterController
,
355 const Anchor eAnchor
)
356 : PresenterToolBarInterfaceBase(m_aMutex
),
357 mxComponentContext(rxContext
),
360 mpPresenterController(rpPresenterController
),
361 mbIsLayoutPending(false),
366 void PresenterToolBar::Initialize (
367 const OUString
& rsConfigurationPath
)
371 CreateControls(rsConfigurationPath
);
375 mxWindow
->addWindowListener(this);
376 mxWindow
->addPaintListener(this);
377 mxWindow
->addMouseListener(this);
378 mxWindow
->addMouseMotionListener(this);
380 Reference
<awt::XWindowPeer
> xPeer (mxWindow
, UNO_QUERY
);
382 xPeer
->setBackground(util::Color(0xff000000));
384 mxWindow
->setVisible(true);
387 mxSlideShowController
= mpPresenterController
->GetSlideShowController();
389 mbIsLayoutPending
= true;
391 catch (RuntimeException
&)
393 mpCurrentContainerPart
.reset();
394 maElementContainer
.clear();
399 PresenterToolBar::~PresenterToolBar()
403 void SAL_CALL
PresenterToolBar::disposing()
407 mxWindow
->removeWindowListener(this);
408 mxWindow
->removePaintListener(this);
409 mxWindow
->removeMouseListener(this);
410 mxWindow
->removeMouseMotionListener(this);
414 // Dispose tool bar elements.
415 for (const auto& rxPart
: maElementContainer
)
417 OSL_ASSERT(rxPart
!= nullptr);
418 for (const rtl::Reference
<Element
>& pElement
: *rxPart
)
422 Reference
<lang::XComponent
> xComponent
= pElement
;
424 xComponent
->dispose();
429 mpCurrentContainerPart
.reset();
430 maElementContainer
.clear();
433 void PresenterToolBar::InvalidateArea (
434 const awt::Rectangle
& rRepaintBox
,
435 const bool bSynchronous
)
437 std::shared_ptr
<PresenterPaintManager
> xManager(mpPresenterController
->GetPaintManager());
440 xManager
->Invalidate(
446 void PresenterToolBar::RequestLayout()
448 mbIsLayoutPending
= true;
450 std::shared_ptr
<PresenterPaintManager
> xManager(mpPresenterController
->GetPaintManager());
454 xManager
->Invalidate(mxWindow
);
457 geometry::RealSize2D
const & PresenterToolBar::GetMinimalSize()
459 if (mbIsLayoutPending
)
461 return maMinimalSize
;
464 const ::rtl::Reference
<PresenterController
>& PresenterToolBar::GetPresenterController() const
466 return mpPresenterController
;
469 const Reference
<XComponentContext
>& PresenterToolBar::GetComponentContext() const
471 return mxComponentContext
;
474 //----- lang::XEventListener -------------------------------------------------
476 void SAL_CALL
PresenterToolBar::disposing (const lang::EventObject
& rEventObject
)
478 if (rEventObject
.Source
== mxWindow
)
482 //----- XWindowListener -------------------------------------------------------
484 void SAL_CALL
PresenterToolBar::windowResized (const awt::WindowEvent
&)
486 mbIsLayoutPending
= true;
489 void SAL_CALL
PresenterToolBar::windowMoved (const awt::WindowEvent
&) {}
491 void SAL_CALL
PresenterToolBar::windowShown (const lang::EventObject
&)
493 mbIsLayoutPending
= true;
496 void SAL_CALL
PresenterToolBar::windowHidden (const lang::EventObject
&) {}
498 //----- XPaintListener --------------------------------------------------------
499 void SAL_CALL
PresenterToolBar::windowPaint (const css::awt::PaintEvent
& rEvent
)
501 if ( ! mxCanvas
.is())
504 if ( ! mbIsPresenterViewActive
)
507 const rendering::ViewState
aViewState (
508 geometry::AffineMatrix2D(1,0,0, 0,1,0),
509 PresenterGeometryHelper::CreatePolygon(rEvent
.UpdateRect
, mxCanvas
->getDevice()));
511 if (mbIsLayoutPending
)
514 Paint(rEvent
.UpdateRect
, aViewState
);
516 // Make the back buffer visible.
517 Reference
<rendering::XSpriteCanvas
> xSpriteCanvas (mxCanvas
, UNO_QUERY
);
518 if (xSpriteCanvas
.is())
519 xSpriteCanvas
->updateScreen(false);
522 //----- XMouseListener --------------------------------------------------------
523 void SAL_CALL
PresenterToolBar::mousePressed (const css::awt::MouseEvent
& rEvent
)
526 CheckMouseOver(rEvent
, true, true);
529 void SAL_CALL
PresenterToolBar::mouseReleased (const css::awt::MouseEvent
& rEvent
)
532 CheckMouseOver(rEvent
, true);
535 void SAL_CALL
PresenterToolBar::mouseEntered (const css::awt::MouseEvent
& rEvent
)
538 CheckMouseOver(rEvent
, true);
541 void SAL_CALL
PresenterToolBar::mouseExited (const css::awt::MouseEvent
& rEvent
)
544 CheckMouseOver(rEvent
, false);
547 //----- XMouseMotionListener --------------------------------------------------
549 void SAL_CALL
PresenterToolBar::mouseMoved (const css::awt::MouseEvent
& rEvent
)
552 CheckMouseOver(rEvent
, true);
555 void SAL_CALL
PresenterToolBar::mouseDragged (const css::awt::MouseEvent
&)
560 //----- XDrawView -------------------------------------------------------------
562 void SAL_CALL
PresenterToolBar::setCurrentPage (const Reference
<drawing::XDrawPage
>& rxSlide
)
564 if (rxSlide
!= mxCurrentSlide
)
566 mxCurrentSlide
= rxSlide
;
571 Reference
<drawing::XDrawPage
> SAL_CALL
PresenterToolBar::getCurrentPage()
573 return mxCurrentSlide
;
577 void PresenterToolBar::CreateControls (
578 const OUString
& rsConfigurationPath
)
580 if ( ! mxWindow
.is())
583 // Expand the macro in the bitmap file names.
584 PresenterConfigurationAccess
aConfiguration (
586 "/org.openoffice.Office.PresenterScreen/",
587 PresenterConfigurationAccess::READ_ONLY
);
589 mpCurrentContainerPart
= std::make_shared
<ElementContainerPart
>();
590 maElementContainer
.clear();
591 maElementContainer
.push_back(mpCurrentContainerPart
);
593 Reference
<container::XHierarchicalNameAccess
> xToolBarNode (
594 aConfiguration
.GetConfigurationNode(rsConfigurationPath
),
596 if (!xToolBarNode
.is())
599 Reference
<container::XNameAccess
> xEntries (
600 PresenterConfigurationAccess::GetConfigurationNode(xToolBarNode
, "Entries"),
603 aContext
.mxPresenterHelper
= mpPresenterController
->GetPresenterHelper();
604 aContext
.mxCanvas
= mxCanvas
;
606 && aContext
.mxPresenterHelper
.is()
607 && aContext
.mxCanvas
.is())
609 PresenterConfigurationAccess::ForAll(
611 [this, &aContext
] (OUString
const&, uno::Reference
<beans::XPropertySet
> const& xProps
)
613 return this->ProcessEntry(xProps
, aContext
);
618 void PresenterToolBar::ProcessEntry (
619 const Reference
<beans::XPropertySet
>& rxProperties
,
620 Context
const & rContext
)
622 if ( ! rxProperties
.is())
625 // Type has to be present.
627 if ( ! (PresenterConfigurationAccess::GetProperty(rxProperties
, "Type") >>= sType
))
630 // Read mode specific values.
631 SharedElementMode pNormalMode
= std::make_shared
<ElementMode
>();
632 SharedElementMode pMouseOverMode
= std::make_shared
<ElementMode
>();
633 SharedElementMode pSelectedMode
= std::make_shared
<ElementMode
>();
634 SharedElementMode pDisabledMode
= std::make_shared
<ElementMode
>();
635 SharedElementMode pMouseOverSelectedMode
= std::make_shared
<ElementMode
>();
636 pNormalMode
->ReadElementMode(rxProperties
, "Normal", pNormalMode
, rContext
);
637 pMouseOverMode
->ReadElementMode(rxProperties
, "MouseOver", pNormalMode
, rContext
);
638 pSelectedMode
->ReadElementMode(rxProperties
, "Selected", pNormalMode
, rContext
);
639 pDisabledMode
->ReadElementMode(rxProperties
, "Disabled", pNormalMode
, rContext
);
640 pMouseOverSelectedMode
->ReadElementMode(rxProperties
, "MouseOverSelected", pSelectedMode
, rContext
);
642 // Create new element.
643 ::rtl::Reference
<Element
> pElement
;
644 if ( sType
== "Button" )
645 pElement
= Button::Create(this);
646 else if ( sType
== "CurrentTimeLabel" )
647 pElement
= CurrentTimeLabel::Create(this);
648 else if ( sType
== "PresentationTimeLabel" )
649 pElement
= PresentationTimeLabel::Create(this);
650 else if ( sType
== "VerticalSeparator" )
651 pElement
.set(new VerticalSeparator(this));
652 else if ( sType
== "HorizontalSeparator" )
653 pElement
.set(new HorizontalSeparator(this));
654 else if ( sType
== "Label" )
655 pElement
.set(new Label(this));
656 else if ( sType
== "ChangeOrientation" )
658 mpCurrentContainerPart
= std::make_shared
<ElementContainerPart
>();
659 maElementContainer
.push_back(mpCurrentContainerPart
);
664 pElement
->SetModes( pNormalMode
, pMouseOverMode
, pSelectedMode
, pDisabledMode
, pMouseOverSelectedMode
);
665 pElement
->UpdateState();
666 if (mpCurrentContainerPart
)
667 mpCurrentContainerPart
->push_back(pElement
);
671 void PresenterToolBar::Layout (
672 const Reference
<rendering::XCanvas
>& rxCanvas
)
674 if (maElementContainer
.empty())
677 mbIsLayoutPending
= false;
679 const awt::Rectangle
aWindowBox (mxWindow
->getPosSize());
680 ::std::vector
<geometry::RealSize2D
> aPartSizes (maElementContainer
.size());
681 geometry::RealSize2D
aTotalSize (0,0);
682 bool bIsHorizontal (true);
683 sal_Int32
nIndex (0);
684 double nTotalHorizontalGap (0);
685 sal_Int32
nGapCount (0);
686 for (const auto& rxPart
: maElementContainer
)
688 geometry::RealSize2D
aSize (CalculatePartSize(rxCanvas
, rxPart
, bIsHorizontal
));
690 // Remember the size of each part for later.
691 aPartSizes
[nIndex
] = aSize
;
693 // Add gaps between elements.
694 if (rxPart
->size()>1 && bIsHorizontal
)
696 nTotalHorizontalGap
+= (rxPart
->size() - 1) * gnGapSize
;
697 nGapCount
+= rxPart
->size() - 1;
700 // Orientation changes for each part.
701 bIsHorizontal
= !bIsHorizontal
;
702 // Width is accumulated.
703 aTotalSize
.Width
+= aSize
.Width
;
704 // Height is the maximum height of all parts.
705 aTotalSize
.Height
= ::std::max(aTotalSize
.Height
, aSize
.Height
);
708 // Add gaps between parts.
709 if (maElementContainer
.size() > 1)
711 nTotalHorizontalGap
+= (maElementContainer
.size() - 1) * gnGapSize
;
712 nGapCount
+= maElementContainer
.size()-1;
715 // Done to introduce gap between the end of the toolbar and the last button
716 aTotalSize
.Width
+= gnGapSize
/2;
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 && bIsHorizontal
)
756 aBoundingBox
.X2
+= (rxPart
->size() - 1) * nGapWidth
;
758 LayoutPart(rxCanvas
, rxPart
, aBoundingBox
, aPartSizes
[nIndex
], bIsHorizontal
);
759 bIsHorizontal
= !bIsHorizontal
;
760 nX
+= aBoundingBox
.X2
- aBoundingBox
.X1
+ nGapWidth
;
765 ElementContainer::iterator iPart
;
766 ElementContainer::iterator
iBegin (maElementContainer
.begin());
767 for (iPart
=maElementContainer
.end()-1, nIndex
=2; iPart
!=iBegin
-1; --iPart
, --nIndex
)
769 geometry::RealRectangle2D
aBoundingBox(
771 nX
+aPartSizes
[nIndex
].Width
, nY
+aTotalSize
.Height
);
773 // Add space for gaps between elements.
774 if ((*iPart
)->size() > 1)
776 aBoundingBox
.X2
+= ((*iPart
)->size()-1) * nGapWidth
;
778 LayoutPart(rxCanvas
, *iPart
, aBoundingBox
, aPartSizes
[nIndex
], bIsHorizontal
);
779 bIsHorizontal
= !bIsHorizontal
;
780 nX
+= aBoundingBox
.X2
- aBoundingBox
.X1
+ nGapWidth
;
784 // The whole window has to be repainted.
785 std::shared_ptr
<PresenterPaintManager
> xManager(mpPresenterController
->GetPaintManager());
788 xManager
->Invalidate(mxWindow
);
791 geometry::RealSize2D
PresenterToolBar::CalculatePartSize (
792 const Reference
<rendering::XCanvas
>& rxCanvas
,
793 const SharedElementContainerPart
& rpPart
,
794 const bool bIsHorizontal
)
796 geometry::RealSize2D
aTotalSize (0,0);
800 // Calculate the summed width of all elements.
801 for (const auto& rxElement
: *rpPart
)
806 const awt::Size
aBSize (rxElement
->GetBoundingSize(rxCanvas
));
809 aTotalSize
.Width
+= aBSize
.Width
;
810 if (aBSize
.Height
> aTotalSize
.Height
)
811 aTotalSize
.Height
= aBSize
.Height
;
815 aTotalSize
.Height
+= aBSize
.Height
;
816 if (aBSize
.Width
> aTotalSize
.Width
)
817 aTotalSize
.Width
= aBSize
.Width
;
824 void PresenterToolBar::LayoutPart (
825 const Reference
<rendering::XCanvas
>& rxCanvas
,
826 const SharedElementContainerPart
& rpPart
,
827 const geometry::RealRectangle2D
& rBoundingBox
,
828 const geometry::RealSize2D
& rPartSize
,
829 const bool bIsHorizontal
)
832 if (rpPart
->size() > 1)
835 nGap
= (rBoundingBox
.X2
- rBoundingBox
.X1
- rPartSize
.Width
) / (rpPart
->size()-1);
837 nGap
= (rBoundingBox
.Y2
- rBoundingBox
.Y1
- rPartSize
.Height
) / (rpPart
->size()-1);
840 // Place the elements.
841 double nX (rBoundingBox
.X1
);
842 double nY (rBoundingBox
.Y1
);
844 /// check whether RTL interface or not
845 if(!AllSettings::GetLayoutRTL()){
846 for (auto& rxElement
: *rpPart
)
851 const awt::Size
aElementSize (rxElement
->GetBoundingSize(rxCanvas
));
854 if (rxElement
->IsFilling())
856 nY
= rBoundingBox
.Y1
;
857 rxElement
->SetSize(geometry::RealSize2D(aElementSize
.Width
, rBoundingBox
.Y2
- rBoundingBox
.Y1
));
860 nY
= rBoundingBox
.Y1
+ (rBoundingBox
.Y2
-rBoundingBox
.Y1
- aElementSize
.Height
) / 2;
861 rxElement
->SetLocation(awt::Point(sal_Int32(0.5 + nX
), sal_Int32(0.5 + nY
)));
862 nX
+= aElementSize
.Width
+ nGap
;
866 if (rxElement
->IsFilling())
868 nX
= rBoundingBox
.X1
;
869 rxElement
->SetSize(geometry::RealSize2D(rBoundingBox
.X2
- rBoundingBox
.X1
, aElementSize
.Height
));
872 nX
= rBoundingBox
.X1
+ (rBoundingBox
.X2
-rBoundingBox
.X1
- aElementSize
.Width
) / 2;
873 rxElement
->SetLocation(awt::Point(sal_Int32(0.5 + nX
), sal_Int32(0.5 + nY
)));
874 nY
+= aElementSize
.Height
+ nGap
;
879 ElementContainerPart::const_iterator iElement
;
880 ElementContainerPart::const_iterator
iBegin (rpPart
->begin());
882 for (iElement
=rpPart
->end()-1; iElement
!=iBegin
-1; --iElement
)
884 if (iElement
->get() == nullptr)
887 const awt::Size
aElementSize ((*iElement
)->GetBoundingSize(rxCanvas
));
890 if ((*iElement
)->IsFilling())
892 nY
= rBoundingBox
.Y1
;
893 (*iElement
)->SetSize(geometry::RealSize2D(aElementSize
.Width
, rBoundingBox
.Y2
- rBoundingBox
.Y1
));
896 nY
= rBoundingBox
.Y1
+ (rBoundingBox
.Y2
-rBoundingBox
.Y1
- aElementSize
.Height
) / 2;
897 (*iElement
)->SetLocation(awt::Point(sal_Int32(0.5 + nX
), sal_Int32(0.5 + nY
)));
898 nX
+= aElementSize
.Width
+ nGap
;
902 // reverse presentation time with current time
903 if (iElement
==iBegin
){
906 else if (iElement
==iBegin
+2){
909 const awt::Size
aNewElementSize ((*iElement
)->GetBoundingSize(rxCanvas
));
910 if ((*iElement
)->IsFilling())
912 nX
= rBoundingBox
.X1
;
913 (*iElement
)->SetSize(geometry::RealSize2D(rBoundingBox
.X2
- rBoundingBox
.X1
, aNewElementSize
.Height
));
916 nX
= rBoundingBox
.X1
+ (rBoundingBox
.X2
-rBoundingBox
.X1
- aNewElementSize
.Width
) / 2;
917 (*iElement
)->SetLocation(awt::Point(sal_Int32(0.5 + nX
), sal_Int32(0.5 + nY
)));
918 nY
+= aNewElementSize
.Height
+ nGap
;
920 // return the index as it was before the reversing
921 if (iElement
==iBegin
)
923 else if (iElement
==iBegin
+2)
930 void PresenterToolBar::Paint (
931 const awt::Rectangle
& rUpdateBox
,
932 const rendering::ViewState
& rViewState
)
934 OSL_ASSERT(mxCanvas
.is());
936 for (const auto& rxPart
: maElementContainer
)
938 for (auto& rxElement
: *rxPart
)
942 if ( ! rxElement
->IsOutside(rUpdateBox
))
943 rxElement
->Paint(mxCanvas
, rViewState
);
949 void PresenterToolBar::UpdateSlideNumber()
951 if( mxSlideShowController
.is() )
953 for (const auto& rxPart
: maElementContainer
)
955 for (auto& rxElement
: *rxPart
)
958 rxElement
->CurrentSlideHasChanged();
964 void PresenterToolBar::CheckMouseOver (
965 const css::awt::MouseEvent
& rEvent
,
966 const bool bOverWindow
,
967 const bool bMouseDown
)
969 css::awt::MouseEvent rTemp
=rEvent
;
970 if(AllSettings::GetLayoutRTL()){
971 awt::Rectangle aWindowBox
= mxWindow
->getPosSize();
972 rTemp
.X
=aWindowBox
.Width
-rTemp
.X
;
974 for (const auto& rxPart
: maElementContainer
)
976 for (auto& rxElement
: *rxPart
)
981 awt::Rectangle
aBox (rxElement
->GetBoundingBox());
982 const bool bIsOver
= bOverWindow
984 && aBox
.Width
+aBox
.X
-1 >= rTemp
.X
986 && aBox
.Height
+aBox
.Y
-1 >= rTemp
.Y
;
989 bIsOver
&& rTemp
.Buttons
!=0 && bMouseDown
&& rTemp
.ClickCount
>0);
994 void PresenterToolBar::ThrowIfDisposed() const
996 if (rBHelper
.bDisposed
|| rBHelper
.bInDispose
)
998 throw lang::DisposedException (
999 "PresenterToolBar has already been disposed",
1000 const_cast<uno::XWeak
*>(static_cast<const uno::XWeak
*>(this)));
1004 //===== PresenterToolBarView ==================================================
1006 PresenterToolBarView::PresenterToolBarView (
1007 const Reference
<XComponentContext
>& rxContext
,
1008 const Reference
<XResourceId
>& rxViewId
,
1009 const Reference
<frame::XController
>& rxController
,
1010 const ::rtl::Reference
<PresenterController
>& rpPresenterController
)
1011 : PresenterToolBarViewInterfaceBase(m_aMutex
),
1013 mpPresenterController(rpPresenterController
)
1017 Reference
<XControllerManager
> xCM (rxController
, UNO_QUERY_THROW
);
1018 Reference
<XConfigurationController
> xCC(xCM
->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 const ::rtl::Reference
<PresenterToolBar
>& rpToolBar
)
1130 : ElementInterfaceBase(m_aMutex
),
1131 mpToolBar(rpToolBar
),
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 ==================================================================
1608 const OUString
& rsText
,
1609 const PresenterTheme::SharedFontDescriptor
& rpFont
)
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(nHours
);
1706 const OUString
sMinutes (OUString::number(nMinutes
));
1707 if (sMinutes
.getLength() == 1)
1709 sText
.append(sMinutes
);
1713 const OUString
sSeconds (OUString::number(nSeconds
));
1714 if (sSeconds
.getLength() == 1)
1716 sText
.append(sSeconds
);
1717 return sText
.makeStringAndClear();
1720 //===== TimeLabel =============================================================
1722 TimeLabel::TimeLabel (const ::rtl::Reference
<PresenterToolBar
>& rpToolBar
)
1727 void SAL_CALL
TimeLabel::disposing()
1729 PresenterClockTimer::Instance(mpToolBar
->GetComponentContext())->RemoveListener(mpListener
);
1733 void TimeLabel::ConnectToTimer()
1735 mpListener
= std::make_shared
<Listener
>(this);
1736 PresenterClockTimer::Instance(mpToolBar
->GetComponentContext())->AddListener(mpListener
);
1739 //===== CurrentTimeLabel ======================================================
1741 ::rtl::Reference
<Element
> CurrentTimeLabel::Create (
1742 const ::rtl::Reference
<PresenterToolBar
>& rpToolBar
)
1744 ::rtl::Reference
<TimeLabel
> pElement(new CurrentTimeLabel(rpToolBar
));
1745 pElement
->ConnectToTimer();
1749 CurrentTimeLabel::~CurrentTimeLabel()
1753 CurrentTimeLabel::CurrentTimeLabel (
1754 const ::rtl::Reference
<PresenterToolBar
>& rpToolBar
)
1755 : TimeLabel(rpToolBar
)
1759 void CurrentTimeLabel::TimeHasChanged (const oslDateTime
& rCurrentTime
)
1761 SetText(TimeFormatter::FormatTime(rCurrentTime
));
1765 void CurrentTimeLabel::SetModes (
1766 const SharedElementMode
& rpNormalMode
,
1767 const SharedElementMode
& rpMouseOverMode
,
1768 const SharedElementMode
& rpSelectedMode
,
1769 const SharedElementMode
& rpDisabledMode
,
1770 const SharedElementMode
& rpMouseOverSelectedMode
)
1772 TimeLabel::SetModes(rpNormalMode
, rpMouseOverMode
, rpSelectedMode
, rpDisabledMode
, rpMouseOverSelectedMode
);
1773 SetText(TimeFormatter::FormatTime(PresenterClockTimer::GetCurrentTime()));
1776 //===== PresentationTimeLabel =================================================
1778 ::rtl::Reference
<Element
> PresentationTimeLabel::Create (
1779 const ::rtl::Reference
<PresenterToolBar
>& rpToolBar
)
1781 ::rtl::Reference
<TimeLabel
> pElement(new PresentationTimeLabel(rpToolBar
));
1782 pElement
->ConnectToTimer();
1786 PresentationTimeLabel::~PresentationTimeLabel()
1788 mpToolBar
->GetPresenterController()->SetPresentationTime(nullptr);
1791 PresentationTimeLabel::PresentationTimeLabel (
1792 const ::rtl::Reference
<PresenterToolBar
>& rpToolBar
)
1793 : TimeLabel(rpToolBar
),
1797 setPauseStatus(false);
1798 TimeValue
pauseTime(0,0);
1799 setPauseTimeValue(pauseTime
);
1800 mpToolBar
->GetPresenterController()->SetPresentationTime(this);
1803 void PresentationTimeLabel::restart()
1805 TimeValue
pauseTime(0, 0);
1806 setPauseTimeValue(pauseTime
);
1807 maStartTimeValue
.Seconds
= 0;
1808 maStartTimeValue
.Nanosec
= 0;
1811 bool PresentationTimeLabel::isPaused()
1816 void PresentationTimeLabel::setPauseStatus(const bool pauseStatus
)
1818 paused
= pauseStatus
;
1821 const TimeValue
& PresentationTimeLabel::getPauseTimeValue() const
1823 return pauseTimeValue
;
1826 void PresentationTimeLabel::setPauseTimeValue(const TimeValue pauseTime
)
1828 //store the time at which the presentation was paused
1829 pauseTimeValue
= pauseTime
;
1832 void PresentationTimeLabel::TimeHasChanged (const oslDateTime
& rCurrentTime
)
1834 TimeValue aCurrentTimeValue
;
1835 if (!osl_getTimeValueFromDateTime(&rCurrentTime
, &aCurrentTimeValue
))
1838 if (maStartTimeValue
.Seconds
==0 && maStartTimeValue
.Nanosec
==0)
1840 // This method is called for the first time. Initialize the
1841 // start time. The start time is rounded to nearest second to
1842 // keep the time updates synchronized with the current time label.
1843 maStartTimeValue
= aCurrentTimeValue
;
1844 if (maStartTimeValue
.Nanosec
>= 500000000)
1845 maStartTimeValue
.Seconds
+= 1;
1846 maStartTimeValue
.Nanosec
= 0;
1849 //The start time value is incremented by the amount of time
1850 //the presentation was paused for in order to continue the
1851 //timer from the same position
1854 TimeValue pauseTime
= getPauseTimeValue();
1855 if(pauseTime
.Seconds
!= 0 || pauseTime
.Nanosec
!= 0)
1857 TimeValue
incrementValue(0, 0);
1858 incrementValue
.Seconds
= aCurrentTimeValue
.Seconds
- pauseTime
.Seconds
;
1859 if(pauseTime
.Nanosec
> aCurrentTimeValue
.Nanosec
)
1861 incrementValue
.Nanosec
= 1000000000 + aCurrentTimeValue
.Nanosec
- pauseTime
.Nanosec
;
1865 incrementValue
.Nanosec
= aCurrentTimeValue
.Nanosec
- pauseTime
.Nanosec
;
1868 maStartTimeValue
.Seconds
+= incrementValue
.Seconds
;
1869 maStartTimeValue
.Nanosec
+= incrementValue
.Nanosec
;
1870 if(maStartTimeValue
.Nanosec
>= 1000000000)
1872 maStartTimeValue
.Seconds
+= 1;
1873 maStartTimeValue
.Nanosec
-= 1000000000;
1876 TimeValue
pauseTime_(0, 0);
1877 setPauseTimeValue(pauseTime_
);
1882 TimeValue pauseTime
= getPauseTimeValue();
1883 if(pauseTime
.Seconds
== 0 && pauseTime
.Nanosec
== 0)
1885 setPauseTimeValue(aCurrentTimeValue
);
1889 TimeValue aElapsedTimeValue
;
1890 aElapsedTimeValue
.Seconds
= aCurrentTimeValue
.Seconds
- maStartTimeValue
.Seconds
;
1891 aElapsedTimeValue
.Nanosec
= aCurrentTimeValue
.Nanosec
- maStartTimeValue
.Nanosec
;
1893 oslDateTime aElapsedDateTime
;
1894 if (osl_getDateTimeFromTimeValue(&aElapsedTimeValue
, &aElapsedDateTime
) && !isPaused())
1896 SetText(TimeFormatter::FormatTime(aElapsedDateTime
));
1901 void PresentationTimeLabel::SetModes (
1902 const SharedElementMode
& rpNormalMode
,
1903 const SharedElementMode
& rpMouseOverMode
,
1904 const SharedElementMode
& rpSelectedMode
,
1905 const SharedElementMode
& rpDisabledMode
,
1906 const SharedElementMode
& rpMouseOverSelectedMode
)
1908 TimeLabel::SetModes(rpNormalMode
, rpMouseOverMode
, rpSelectedMode
, rpDisabledMode
, rpMouseOverSelectedMode
);
1910 oslDateTime aStartDateTime
;
1911 if (osl_getDateTimeFromTimeValue(&maStartTimeValue
, &aStartDateTime
))
1913 SetText(TimeFormatter::FormatTime(aStartDateTime
));
1917 //===== VerticalSeparator =====================================================
1919 VerticalSeparator::VerticalSeparator (
1920 const ::rtl::Reference
<PresenterToolBar
>& rpToolBar
)
1921 : Element(rpToolBar
)
1925 void VerticalSeparator::Paint (
1926 const Reference
<rendering::XCanvas
>& rxCanvas
,
1927 const rendering::ViewState
& rViewState
)
1929 OSL_ASSERT(rxCanvas
.is());
1931 awt::Rectangle
aBBox (GetBoundingBox());
1933 rendering::RenderState
aRenderState(
1934 geometry::AffineMatrix2D(1,0,aBBox
.X
, 0,1,aBBox
.Y
),
1936 Sequence
<double>(4),
1937 rendering::CompositeOperation::OVER
);
1940 PresenterTheme::SharedFontDescriptor
pFont (mpMode
->maText
.GetFont());
1942 PresenterCanvasHelper::SetDeviceColor(aRenderState
, pFont
->mnColor
);
1945 Reference
<rendering::XBitmap
> xBitmap(mpToolBar
->GetPresenterController()->GetPresenterHelper()->loadBitmap("bitmaps/Separator.png", rxCanvas
));
1949 rxCanvas
->drawBitmap(
1955 awt::Size
VerticalSeparator::CreateBoundingSize (
1956 const Reference
<rendering::XCanvas
>&)
1958 return awt::Size(1,20);
1961 bool VerticalSeparator::IsFilling() const
1966 //===== HorizontalSeparator ===================================================
1968 HorizontalSeparator::HorizontalSeparator (
1969 const ::rtl::Reference
<PresenterToolBar
>& rpToolBar
)
1970 : Element(rpToolBar
)
1974 void HorizontalSeparator::Paint (
1975 const Reference
<rendering::XCanvas
>& rxCanvas
,
1976 const rendering::ViewState
& rViewState
)
1978 OSL_ASSERT(rxCanvas
.is());
1980 awt::Rectangle
aBBox (GetBoundingBox());
1982 rendering::RenderState
aRenderState(
1983 geometry::AffineMatrix2D(1,0,0, 0,1,0),
1985 Sequence
<double>(4),
1986 rendering::CompositeOperation::OVER
);
1989 PresenterTheme::SharedFontDescriptor
pFont (mpMode
->maText
.GetFont());
1991 PresenterCanvasHelper::SetDeviceColor(aRenderState
, pFont
->mnColor
);
1994 rxCanvas
->fillPolyPolygon(
1995 PresenterGeometryHelper::CreatePolygon(aBBox
, rxCanvas
->getDevice()),
2000 awt::Size
HorizontalSeparator::CreateBoundingSize (
2001 const Reference
<rendering::XCanvas
>&)
2003 return awt::Size(20,1);
2006 bool HorizontalSeparator::IsFilling() const
2011 } // end of anonymous namespace
2013 } // end of namespace ::sdext::presenter
2015 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */